トップページ⇒php
1001コメント313KB

【Perl】初心者コーナー Part19

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん03/02/09 00:24ID:s0tpWWxg
初めに→「perl」その物のスレです。

1:自分はこう言う事がしたい。
2:それでこんな風にやってみたが・・・
3:それだとこんなエラーが出て上手く行かなかった。

1と3が無いと誰も答えられないよ。
良い回答は良い質問から。一緒に勉強しましょう。


CGIだけど、なんか質問ある? Part 9
http://pc.2ch.net/test/read.cgi/php/1041530204/
参考書籍の話題は【Perl,CGI】参考書籍 第三版
http://pc.2ch.net/test/read.cgi/php/1030209573/
その他の雑多な話題は、【CGIに依存しないPerlの話題一般/Part2】
http://pc.2ch.net/test/read.cgi/php/1030548610/
スクリプトの改造依頼は 【 スクリプト改造工房 PART 5 】
http://pc.2ch.net/test/read.cgi/php/1028193595/

あとは>>2-10。
0357nobodyさん03/02/22 22:28ID:???
>>356
実は書き込み先がローカルじゃなかった。とか。
0358nobodyさん03/02/22 22:28ID:???
それ、これまでのカウントってどこで読み込んでるの?
0359nobodyさん03/02/22 22:29ID:???
>>356
書き込む前にtruncateせず、
書き込み後にtruncate(OUT, tell(OUT));
0360nobodyさん03/02/22 22:31ID:???
あと、エラー処理入れれ。
0361nobodyさん03/02/22 22:35ID:???
要は、小出しにしたソースでは的確なアドバイスはできないってことだ。
0362nobodyさん03/02/22 22:36ID:???
>>356
読み出しと書き込みを一回で処理。
036335403/02/22 22:53ID:dmtEQjtb
if (open(F, "+< count.dat")) {
flock(F, 2);
$count = <F>;
$count++;
seek(F, 0, 0);
print F $count;
close(F);
} else {
&error();
}
いろいろ改良して、こんな感じなったんですけど、やっぱり1000回ぐらい何人かでやるとファイルの中身がおかしくなってしまいます
0364nobodyさん03/02/22 22:56ID:???
openのエラー処理しかしてねーじゃねーか。
0365nobodyさん03/02/22 22:59ID:???
「おかしくなる」って、どうおかしくなるの?
処理の結果ってのはバグの手がかりを知る大事な情報だから省略しないように。
036635403/02/22 23:04ID:dmtEQjtb
ファイルにアクセスが多くなると、ファイルの中身の値が適切じゃないものになってしまいます。
0367nobodyさん03/02/22 23:06ID:???
モロ画像とか?
036835403/02/22 23:07ID:dmtEQjtb
いや。同時に大量実行実験です。
それで、実行された回数を記録したいんです。
0369nobodyさん03/02/22 23:09ID:???
>>363
例えば、先行プロセスでflockが失敗したとする。
しかしエラー処理が無いのでそのまま進む。
ここで後続プロセスがロックがかかってないのでファイルをオープンする。
データが壊れる。
0370nobodyさん03/02/22 23:28ID:???
カウンターとかのファイルロックって、
限界があると思うけど・・・。
絶対壊れないようにするファイルロックはないです。
037135403/02/22 23:30ID:dmtEQjtb
では、MySQLのデータペースとか使えば壊れないでしょうか?
0372nobodyさん03/02/22 23:31ID:???
もし壊れても、可能な限り復旧するっていう形のほうがいいかも。
0373nobodyさん03/02/22 23:42ID:???
>>370
でたらめ抜かすな。ロックは2種類しかない。
正しいロックと駄目ロックだ。絶対に壊れないのが正しいロック、それ以外が駄目ロック。
0374nobodyさん03/02/22 23:59ID:???
>>363
truncateしろ。
0375nobodyさん03/02/23 00:02ID:???
>>374
サイズが増えるだけなら入らないと思われ
037635403/02/23 00:04ID:osZUd/C4
>> 374
truncateって何ですか?
0377nobodyさん03/02/23 00:08ID:???
だからエラー処理をしろって
0378nobodyさん03/02/23 00:18ID:???
>>363
その方法が最良じゃないかと思いますが。
無駄な処理とかないですし。
あとはflockとseekとcloseにエラー処理加えるくらいですね。
037937803/02/23 00:19ID:???
ちなみにtrancateは入れる必要ないですね。
0380nobodyさん03/02/23 00:26ID:???
>>373
そんなことない。
絶対壊れないようにするなんて不可能。
集中同時アクセスがつづけば、どんなロックしてても壊れるだろ。
0381nobodyさん03/02/23 00:29ID:???
ムキー!!!
なんで354は再三にわたってエラー処理をしろというレスを
無視するんだああああr;かえ;gk’えあ;rlf’あうぇr
0382nobodyさん03/02/23 00:50ID:???
>>381
まあおちけつ。
どうせ動かなくて困るのは質問した本人だけだ。
0383nobodyさん03/02/23 01:09ID:???
アクセス数を制限してみる。
flockを使わない。
0384nobodyさん03/02/23 01:10ID:???
>>380
それはチミが駄目ロックしか作れないという事を意味する。
0385nobodyさん03/02/23 01:15ID:PmGQRxss
Socketで?を含むURLをGETしようとしてるんですが、&amp; に展開されてしまってうまくいきません。
何とか回避する方法はありませんでしょうか?
0386nobodyさん03/02/23 01:21ID:???
意味不明。
0387nobodyさん03/02/23 01:26ID:???
(再挑戦)

Socketで&を含むURLをGETしようとしてるんですが、&amp; に展開されてしまってうまくいきません。
何とか回避する方法はありませんでしょうか?
0388nobodyさん03/02/23 01:28ID:???
リクエストはどうやって送ってるの?
038938703/02/23 01:30ID:???
$url = "test/read.cgi/php?1044717887";

my $SOCKET = new IO::Socket::INET -> new(PeerAddr => $hostname,
PeerPort => 'http',
Proto => 'tcp',
TimeOut => '5' );
print $SOCKET "GET $url HTTP/1.1\r\n";


ってな感じです。
0390nobodyさん03/02/23 01:39ID:???
&はどこで使っているのでしょうか・・・
039138703/02/23 01:42ID:???
またやっちまった。

$url = "test/read.cgi/php&1044717887";

my $SOCKET = new IO::Socket::INET -> new(PeerAddr => $hostname,
PeerPort => 'http',
Proto => 'tcp',
TimeOut => '5' );
print $SOCKET "GET $url HTTP/1.1\r\n";


ってな感じです。
(この$urlは実在しません)
039238703/02/23 01:46ID:???
これで、エラーが
 Invalid URI in request GET test/read.cgi/php&amp;1044717887 HTTP/1.1<P>
と出ます。
0393nobodyさん03/02/23 01:50ID:???
print $SOCKET "GET /$url HTTP/1.1\r\n";
0394nobodyさん03/02/23 01:53ID:???
>>387
$urlが間違っている。httpのRFC読んで出なおしたまへ。
039538703/02/23 01:53ID:???
>>393
あんりがとうございました。

目から鱗でした〜
039638703/02/23 01:55ID:???
>>394
後学のために、どこが間違いなのかヒントだけでも…
0397nobodyさん03/02/23 01:56ID:???
>>354
参考のためにOS教えて。
# truncateまでしたら、まず壊れないと思うけど。

参考のために。
use IO::File;
my $fh = IO::File->new("count.dat", O_EXLOCK|O_RDWR); # $fhがハンドル
で、ファイル開いてみてください(ただしWindows不可)。

>>387
展開されます?
>>392のサーバのエラーはHTML形式で出力されているようですが。
0398nobodyさん03/02/23 01:59ID:???
>>396
ファイル指定は、ドキュメントルートからのパスで指定しなきゃ。
039938703/02/23 02:11ID:???
>>398
だめだ。。。
意味わからん。出直します。。。
0400nobodyさん03/02/23 02:14ID:???
>>396

http://www.ietf.org/rfc/rfc2616.txt
5.1 Request-Line
Request-Line = Method SP Request-URI SP HTTP-Version CRLF
5.1.2 Request-URI
Request-URI = "*" | absoluteURI | abs_path | authority

http://www.ietf.org/rfc/rfc2396.txt
3. URI Syntactic Components
abs_path = "/" path_segments

ここら辺を読んでくれたまへ。
0401nobodyさん03/02/23 12:17ID:???
米鳥で、htmlファイルを読み込んで編集して出力と言うスクリプトを書いたのですが、
ローカルではopenできるのですが、UPするとhtmlファイルがopenできません。

どうしたら良いでしょうか?
0402nobodyさん03/02/23 12:22ID:???
まずは質問の仕方を勉強して、
このスレの>>1-401を音読してください。
0403nobodyさん03/02/23 12:25ID:???
>>401
エラーメッセージを書け
0404nobodyさん03/02/23 12:41ID:???
>>380
まともなOSなら、まともなロックぐらいできるはずだ。

エラー処理とは...
全てのシステムコールに、or die($!);ってつけて、
eval BLOCK の中で実行してみろ。例外が飛んできたら(?)
$@に入るから、それを出せばいい。
0405nobodyさん03/02/23 18:05ID:???
Windowsで、メールを送信するプログラムのローカルテスト環境を作ることってできますか?
0406nobodyさん03/02/23 18:07ID:???
>>405
CGIだけど、なんか質問ある? Part 9
http://pc2.2ch.net/test/read.cgi/php/1041530204/
0407nobodyさん03/02/23 19:06ID:srUBO4KW
きく
0408nobodyさん03/02/23 19:08ID:???
あのう突然すみませんが、
私のプロバがヤフーBBで今書き込めなくて困っています。
どうしたら書き込みできるようになるんでしょうか。教えてください。
040940803/02/23 19:09ID:???
串を使っても書き込めないのですが......
0410nobodyさん03/02/23 19:14ID:???
>>408
プロバイダを変える。
あと、スレ違いの質問はよせ。
0411nobodyさん03/02/23 19:15ID:???
ファイルの中身を逆順に表示する方法はありますでしょうか。
リストに読み込んでリバースするとなると、メモリ容量が心配でして・・・
0412nobodyさん03/02/23 19:16ID:???
>>410
放置に限ります。
0413nobodyさん03/02/23 21:20ID:???
>>402-403
スクリプトは間違ってなかったのですが
鳥の仕様でスタ(cgi-bin以下のファイルは操作できない)

婆茶とかハイマしか触ったこと無かったので分からなかった(;´Д`)
0414nobodyさん03/02/23 21:22ID:???
>>411
whileで回しつつ、unshiftしていけば?
0415nobodyさん03/02/23 21:26ID:???
>>414
それじゃ最終的にファイル全部を配列に入れるわけだから同じだよ。
まあ、100KBぐらいだったら気にせずreverseでいいんでない?
0416nobodyさん03/02/23 21:57ID:???
>>411
ttp://www.din.or.jp/~ohzaki/perl.htm#File_Reverse
これはどうか。
0417nobodyさん03/02/23 22:21ID:???
>>414-416
レスありがとうございます。
平均100KBくらいなんですが、気にしなくてもいいのかもしれませんね・・
ちょっと>>416さんのところ、詳しく見させてもらいます。
ありがとうございました。
0418nobodyさん03/02/23 22:24ID:???
どうせ一気読みするならforで後ろから逆順に読んでいった方がreverseするより軽いと思われ。
0419nobodyさん03/02/23 23:49ID:???
まわす数が分かっている場合。
$n = 10;
for(1..$n){ 処理; }
と、しているのですがもっとベターなやり方はありますでしょうか?
0420nobodyさん03/02/23 23:50ID:???
全部読むなら、foreachの方が速くなるかも。特化しているから。
0421nobodyさん03/02/24 00:00ID:???
>>420さんありがとうです。
昔はforeachを使っていたのですが、何時の間にか短いforを使うようになってしまいました。
0422nobodyさん03/02/24 01:33ID:???
>>420 特化ってどのへんで?
for と foreach って常に置き換え可能じゃない?
0423nobodyさん03/02/24 08:38ID:???
>>422
しかも今回は逆さに参照。
0424nobodyさん03/02/24 08:45ID:cCE/Sh/G
自作のオブジェクト指向なCGIフレームワークを、公開前にmod_perl環境にも対応させたいです。
mod_perlを極めるためのおすすめ本・サイトを教えてください。
お願いします。
0425nobodyさん03/02/24 09:34ID:???
>>424
・・・・気持ち悪いやつ
0426nobodyさん03/02/24 10:50ID:???
cryptで暗号化しておいた文字列を
ユーザに入力して貰ったデータと照合する処理を実現したいのですが
何度試してみても結果がNGで戻ってきてしまいます
尚、照合処理は下記の様なシンプルなものです

if ($savedata[0] eq substr($chkiddata[1], 0, length($savedata[0]))) {
if (crypt($chkpassdata[1], $savedata[1]) eq $savedata[1]) {
print "password check OK...<br><br>\n";
$flg = 1;
}
}

$chkiddata[0] はユーザ入力にてIDが、$chkpassdata[1] はユーザにて入力されたパスワード文字列(平文)が格納されております
$savedata[0] は保存されているIDが、$savedata[1] は保存されている暗号化済みのパスワード文字列が格納されております
また $flg に 1 が格納されている場合は、check OK の HTML を書き出す処理をおこなっています

因みに、パスワード暗号化を行う処理は、別のPerlスクリプトで行っておりますが、これも何か関係がありますでしょうか

宜しくお願い致します

0427nobodyさん03/02/24 12:20ID:???
>>426
> if ($savedata[0] eq substr($chkiddata[1], 0, length($savedata[0]))) {
$chkiddata[1] は、なんなのさ?
if ($savedata[0] =~ /^$chkiddata[0]/) {
ぢゃなぁぃ?
0428nobodyさん03/02/24 12:27ID:???
>>426
変数が間違っている。
042942403/02/24 12:48ID:???
比較的有用と思われるHTML::Template、CGI::Lite、Apache::Sessionなどを
使い易く統合して機能追加したパッケージを作っいるので、
それがmod_perl環境でも動くように改良したいと思ってるんですが…。
気持ち悪いですか。うあああ。
0430nobodyさん03/02/24 12:59ID:???
>>429
気持ち悪い
043142603/02/24 14:55ID:???
申し訳ないです、記述間違ってました
$chkiddata[1] の方にユーザで入力されたアカウント名が入っています、でした

今しがた print をIDチェック部分に噛ませて実行してみた所
ID 部分のチェックは問題なく認識できている様なのですが
どうしても暗号化パスワードとの比較が NG で戻ってきてしまいます...
0432nobodyさん03/02/24 15:01ID:???
URLエンコードとデコードはきちんとしてる?
043342603/02/24 15:09ID:???
>>432
はい、拾ってくれたデータも print で書き出しテストしてみましたが
問題なく元データとして保持されておりました
0434nobodyさん03/02/24 16:41ID:???
改行コードが付いてるとか。
chop $savedata[1];
043543403/02/24 16:42ID:???
chompでした。
0436nobodyさん03/02/24 17:43ID:???
>>431
目玉開いてよーく見てから、直したの貼って見れ。各変数に何が入っているか説明する事。
0437nobodyさん03/02/24 18:02ID:???
先生いいでつか?

windows2000
Active perl 5.6.1 build 633
APACHE 1.3.27
の環境ですが

exec (又はsystem) で外部プログラムを呼び出したとき
コマンドライン上で実行した場合外部プログラムは問題なく起動するのに
ブラウザから呼び出した場合外部プログラムが起動する場合と
起動しない場合があるのは何故なんでしょう??

hoge.cgi
#!/usr/local/bin/perl
print "Content-type: text/html;charset=euc-jp\n\n"; #コマンドラインから呼び出す場合は要らない
system("program.exe");

外部プログラムはどのような物でも問題なく起動 c:>perl hoge.cgi
起動するものと起動しないものがある http://127.0.0.1/cgi-bin/hoge.cgi
0438nobodyさん03/02/24 18:37ID:???
>>437
起動する場合としない場合の違いを説明する事。
まずはpathが通っているかをチェックしる。

> 先生いいでつか?
このスレに代議士はいない。・・・はず?
0439nobodyさん03/02/24 20:28ID:???
path を通しても同じです。フルパスで指定しても一緒。
違いは今のところパターンが把握できては居ませんが
どうやら何かしらのメッセージを標準出力に出力しないものは
起動していないような気がする。

例えば
system("dir");は
perl hoge.cgi
http://127.0.0.1/cgi-bin/hoge.cgi
共に問題なく動く

system("wmplayer");はブラウザから呼び出したときは動かない(起動しない)。
0440nobodyさん03/02/24 21:04ID:???
標準出力先が違うからね。
Apacheに理解できない出力したらいかんよ。
0441nobodyさん03/02/24 21:26ID:38CGzi2z
現在より nヶ月前の年を算出したいのですがどのように書けばいいでしょうか?

$year = $thisyear + int(( $thismon-1 ) /12 );

で nヶ月後は算出できるのですが…。
0442nobodyさん03/02/24 21:38ID:???
>>441
引き算知ってる?
0443nobodyさん03/02/25 00:21ID:???
http://www.mac68k.com/php/pafiledb3/pafiledb.php?action=file&id=33
ここで落としたphpBB2.0.4をXREAに設置したのですが、
書き込み時に「"」が「?」に、「>」や「<:」が「&」になってしまいます。
phpをいじったの自体初めてで、どうすればいいのやらさっぱりです。
既知の不備等、ご存じの方がおりましたらご教授下さい。
0444nobodyさん03/02/25 00:24ID:???
>>443
ここは作る人用の板。消えろ。
044544303/02/25 03:31ID:???
>>444
大変申し訳ありませんでした。
0446nobodyさん03/02/25 06:42ID:???
phpってのがミソですかな
0447nobodyさん03/02/25 07:17ID:???
どこかで「CGIはこのスレ」とでも誘導してるのか?
理解できん。
0448nobodyさん03/02/25 07:56ID:???
>>447
Web制作
http://pc2.2ch.net/hp/

k
0449nobodyさん03/02/25 11:40ID:???
>448
板にはともかくスレに誘導はしてないだろうよ…
045043703/02/25 15:57ID:???
パターンと原因が掴めなかったので
perlからtelnetで接続させて起動させるように書きました。
まあ、目的は達成できたのでヨシとします。
暇なときにでも勉強するでス。
ありがとう。

余談だがwin9x系だとtelnetdにろくな物が無いのに愕然とした(涙
0451nobodyさん03/02/25 17:11ID:wR5lMZNW
WIN2000+anhttpdでCGIとして動かしています。

systemでファイルのコピー等を行った場合に、「○個のファイルをコピーしました」
などのsystemの返り文字が表示されますが、これをスクリプト上で
非表示にする方法はないものでしょうか。
___________
$from="コピー元パス";
$to="コピー先パス";
system("copy $copyfrom/A $copyto");
→1個のファイルをコピーしました。
___________

ご存知の方いましたらお願いします。
045245103/02/25 17:13ID:wR5lMZNW
訂正:
system("copy $copyfrom/A $copyto"); → system("copy $from/A $to");
0453nobodyさん03/02/25 20:06ID:???
>>451
system("copy $from/A $to > nul.txt");
とかでダミーファイルにリダイレクトするってのはどう。
0454nobodyさん03/02/25 20:33ID:???
ダミーじゃなくても、> nul にリダイレクトだけでいいはずだけど、
anhttpdって、クライアント側への表示を勝手にしちゃうの?
って、気づけばここperlスレだった…。
045545303/02/25 20:57ID:???
/dev/nulでだめだったので使えないのかと思った。
/devディレクトリないからあたりまえか。
0456nobodyさん03/02/25 21:47ID:???
>>455
nulはデバイスだよ。ファイルとかディレクトリじゃないからパス名はつけられない。
逆にパス名つけたらただのファイルになっちゃう。

■ このスレッドは過去ログ倉庫に格納されています