Perl コーディング初心者質問コーナー Part34
■ このスレッドは過去ログ倉庫に格納されています
0001前スレの連投で気分崩したので後よろ
04/04/05 16:01ID:???【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。
1: 自分はこう言う事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。
過去ログやお勧めサイトは >>2-10
0313nobodyさん
04/04/19 16:06ID:???〜 or die; とするぐらいならどうしてもう一歩すすめて 〜 or die "適当なメッセージ: $!"
としないのか...
0314nobodyさん
04/04/19 16:46ID:???print "Content-type: text/html\n\n";
の前に鰓が出て、「ぷりめちゃ〜」って出るからなんじゃなぁい?(w
0315nobodyさん
04/04/19 17:03ID:???@array を : で2つに分けて片方だけ表示したいのですが。
下記のように記述してみましたが、できませんでした。
書き方が違うのだと思います。
教えていただけませんか?
while (@array){
($hour, $min) = split (/./, "$array[$_]");
}
print "Content-type: text/html\n\n";
print "<HTML><BODY>\n";
foreach (@array){
print $hour[$_],\n;
}
今のままだと動作がものすごく遅くて
結局最後にエラー表示がでてしまいます。
一応、文法的な間違いはないようですが・・・・・・。
0316nobodyさん
04/04/19 17:05ID:???0317nobodyさん
04/04/19 17:07ID:???>@array を : で2つに分けて
意味がわからん
>while (@array){
>($hour, $min) = split (/./, "$array[$_]");
>}
これはどういう処理してるつもり?
0318nobodyさん
04/04/19 17:17ID:ZjO/sTltたかし
たろう
こういち
さぶろう
よしゆき
みたいなテキストファイルがあって、
それを読み込んで
「ぬるぽ」をHTMLから送信すると
ぬるぽ
たかし
たろう
こういち
さぶろう
よしゆき
見たいな感じにテキストファイルの一番上の列に
書き出すことはできますか?
またできるのでしたらその方法を教えていただけますか?
0319nobodyさん
04/04/19 17:21ID:???print "Content-type: text/html\n\n";
print "<HTML><BODY>\n";
foreach (@array){
($hour, $min) = split (/:/);
print $hour,"<br>\n";
}
0320nobodyさん
04/04/19 17:26ID:???http://www.kt.rim.or.jp/%7ekbk/perl5.005/perlfaq5.html#How_do_I_change_one_line_in_a_fi
0322nobodyさん
04/04/19 20:05ID:FJ2iv18Nそのまま標準出力にバイナリーデータとして返すにはどうすればよいのでしょうか。
読み込むにはbinmodeを呼び、通常通りreadにて$???で受け取ってよいのでしょうか、
またバイナリーをアウトプットする関数名を教えて下さい。
0323nobodyさん
04/04/19 20:14ID:???0325nobodyさん
04/04/19 20:22ID:???とりあえずパスワードを変えることでしのいだのですが、
管理画面のログをとりたいと思っています。
CGIをいじったことはあまりないのですが、
管理画面(admin.cgi)の2行目くらいにreqireでアクセス解析のCGIを指定してやればいいのでしょうか?
よろしくお願いします。
0327323
04/04/19 20:29ID:???誤爆した
0328nobodyさん
04/04/19 21:10ID:BDbOGV6Pperlで掲示板を作成しました。
掲示板の内容はログに書込まずにDB(PostgreSQL)に書込まれるようにしました。
出力するときにDBから取り出して、値を $変数 =~ s/\r/<br>/g;
という処理にして表示させると、改行はされますが、改行位置に<br>が付いた状態で表示されて
しまいます。<br>を非表示にして表示できないものでしょうか?
0329nobodyさん
04/04/19 21:13ID:???open(FILE,"ファイル名");
binmode(FILE);
binmode(STDOUT);
print <FILE>;
close(FILE);
0331nobodyさん
04/04/19 21:53ID:???とりあえず、アクセス解析ぐらい(admin.cgi)とやらに自力で書き加えれる程度の知識つけて
実際に書き加えてみろ。
そんで、うまく動かないとか、なんか困っ時にまた来なさい。
話はそれからだ。
0334nobodyさん
04/04/20 20:34ID:???あいまいだな
0335nobodyさん
04/04/20 21:07ID:???$変数 =~ s/\r/<br>/g;
$変数 =~ s/</</g;
$変数 =~ s/>/>/g;
ってなってて <pre> で囲まれてるんじゃない?
0336nobodyさん
04/04/20 21:56ID:yCtk22ceをperlで書く場合は
( x >= 1) and ( x <= 100 )
と書けば動きますが、もっとスマートな書き方ってあります?
0337nobodyさん
04/04/20 22:14ID:Z+bRhQSh0338nobodyさん
04/04/20 23:56ID:???控え用にあるccが機能しません。
管理者用に届くメールのccに書いたほうのメールアドレスが
書いてあることには書いてあるんですが届かないのは
どんな理由が考えられますでしょうか?
0339nobodyさん
04/04/21 00:36ID:???0342nobodyさん
04/04/21 02:51ID:???0343nobodyさん
04/04/21 03:12ID:???0344nobodyさん
04/04/21 03:23ID:???0345nobodyさん
04/04/21 03:40ID:???0346nobodyさん
04/04/21 13:55ID:hvmubjIuopen F,'test.txt';
flock F, 1;
$data = <F>;
close F;
$data++;
open F,"+<test.txt";
flock F, 2;
truncate F, 0;
print F $data ;
close F;
}
これを、2プロセスで実行すると、+2000になる予定ですが、+2000になりません。
printの前に seek F,0,0; を入れると期待通り+2000になるのですが・・・。
どうしてでしょうか?
0347nobodyさん
04/04/21 14:26ID:???http://www.kt.rim.or.jp/%7ekbk/perl5.005/perlfaq5.html#I_still_don_t_get_locking_I_jus
0348nobodyさん
04/04/21 15:41ID:???カウンタファイルを読むのと書くのをそれぞれ別のロックにしたら
相手の操作に割り込まれ放題だから2000にならないのは不思議
でもなんでもないが、seekを入れただけで2000になるのはとても
不思議だ。オレにはわからん。
0349nobodyさん
04/04/21 15:45ID:???my $fh = 'FILE';
open($fh, '< file.txt') or die $!;
のように。
0350nobodyさん
04/04/21 15:58ID:???http://www.kt.rim.or.jp/%7ekbk/perl5.005/perlfaq5.html#How_can_I_use_a_filehandle_indir
0351nobodyさん
04/04/21 22:29ID:dqfm18bp$data = "example";
この時にprint "$change";とすると$dataと出力されてしまうのですが、
この時exampleを出力させる様にするにはどのようにしたら良いでしょうか?
どなたかご教授お願い致します。
0352351
04/04/21 22:29ID:???0353336
04/04/21 22:30ID:???( $x >= 1) and ($x <= 100 )
に関して言えば、可読性からもこれでいいのかな。
レスくれたひとサンクス。
0354nobodyさん
04/04/21 22:30ID:???0355レファランス使え
04/04/21 23:08ID:???$change = "data";
$data = 'example';
print $$change,"\n";
$change = \$data;
$data = 'example';
print $$change,"\n";
0356nobodyさん
04/04/21 23:21ID:???$change = '$data';
$data = "example";
print eval $change;
0357nobodyさん
04/04/21 23:23ID:???0358351
04/04/22 00:03ID:???早速組み込んでみた所、期待通りの動作をしました。Perlにもポインタの様な物が実装されているんですね。
これを機にevalの使い方も覚えました。ありがとうございました。
0359nobodyさん
04/04/22 00:20ID:???いくつかのファイルをループ処理でまとめて読み取り、
$dat[ファイルNo.][n行目]
のように一つの2次元配列に格納しようとしています。
@dat[$i] = <FH>;
openした直後に上記のようなコードを入れましたが、
どうも配列は1次元のままで、各ファイルの一行目しか配列に格納してくれませんでした。
どなたか2次元で格納させるヒントをご教授ください。
0360nobodyさん
04/04/22 00:27ID:???0361nobodyさん
04/04/22 00:29ID:???関数やサブルーチンからの戻り値をそのまま return する時に
return \(value()) とかやっているのですが、
例えば複数の値の場合に return [values()] で配列のリファレンスを返せるように、
無名スカラーがあれば良いのになあと。
0363361
04/04/22 00:31ID:???0364nobodyさん
04/04/22 02:12ID:???かな?
0365nobodyさん
04/04/22 09:00ID:???無名スカラーって無名スカラーリファレンスってことか?
ハッシュや配列と違って、無名スカラーリファレンスをを作る構文的なサポートは無い。
苦肉の策だが my $anon_sref = do{ my $o; \$o } などとしているな。
しかしこの場合は\(value())ではいけないのか?何か不満か?
0366nobodyさん
04/04/22 12:18ID:???無いのであれば、今まで通りにする事にします。
0367nobodyさん
04/04/23 20:15ID:???はじめの文字がaだった場合とそれ以外で読み込むフォルダを分けたいと
思っています。
以下のように記述したのですが、エラーが出てしまいました・・。
どこ違っているのかわからないので、指導お願いします〜。。
$IMAGE = sprintf("%01d/%01d/%04d",$a,$b,$c);
if ($a eq a){print "<IMG src=\"image/$a$b$c.gif\">;
}else{print "<IMG src=\"img/$a$b$c.gif\">";}
また、1.1.残りと分けたいのですが、画像ファイルの名前が4〜6文字とランダムなのですが、上の書き方だとだめなんですよね・・?
どうすればいいんでしょうか?
0368nobodyさん
04/04/23 20:17ID:???最近アクセス解析CGI作ったから require で呼び出せるように書き換えて
提供してやろうか?
いるなら捨てアドさらせ。
さらしてから書き換えに2〜3日掛かるからその後送ってやる
0369nobodyさん
04/04/23 21:00ID:???print $IMAGE =~ /^A/ ? "<IMG src=\"image/$IMAGE.gif\">" : "<IMG src=\"img/$IMAGE.gif\">";
0370nobodyさん
04/04/23 21:04ID:???>$IMAGEに書かれている文字を、sprintfで文字を3つに(1.1.残り)に分けて
使う関数が目的に合っているかよく調べろ。
>$IMAGE = sprintf("%01d/%01d/%04d",$a,$b,$c);
これじゃあ$a,$b,$cを指定のフォーマットにして/をはさんだ文字列として
$IMAGEに代入する式だ。
こんなのでもいいだろ。
$a = substr($IMAGE,0,1);
$b = substr($IMAGE,1,1);
$c = substr($IMAGE,2);
0371369
04/04/23 21:12ID:???0373nobodyさん
04/04/24 12:42ID:ftCx7p610374nobodyさん
04/04/24 13:44ID:???0375373
04/04/24 14:07ID:???0376nobodyさん
04/04/24 15:41ID:???自分で使う分には構わないって事でファイナルアンサーしてたような。
CPANに登録するのなら英語(Ascii?)で書かかないと。
http://www.perldoc.com/perl5.8.0/README.jp.html
http://search.cpan.org/~nwclark/perl-5.8.4/README.jp
EUC-JPで化けるみたいだしね。
# UTF-8だといけるのかな?
0377373
04/04/24 21:14ID:???お陰で彼女が出来ました
0378nobodyさん
04/04/25 11:23ID:KCQtln8X例えば、MOD_A.pm と MOD_B.pm を自作して
MOD_A.pm 内のソースで use MOD_B; を宣言
MOD_B.pm 内のソースで use MOD_A; を宣言
cgiプログラムを作ってるんですが、そのcgiプログラムの中で
use MOD_A;
use MOD_B;
とかやりたいんですがどう?
もっとさらに言うと、MOD_A.pm の中で自分自身を
use MOD_A;
とかやっても大丈夫ですか?
0379nobodyさん
04/04/25 11:41ID:???0380nobodyさん
04/04/25 11:42ID:???0381nobodyさん
04/04/25 14:33ID:???相互 use、自己 use とも無限ループにはならない。
ttp://www.perldoc.com/perl5.8.0/pod/func/use.html
ttp://www.perldoc.com/perl5.8.0/pod/func/require.html
ただし、自己 use することに何の意味もない。
さらに、相互 use することにも意味がない。
>378 の例だと CGI の中の use MOD_B; と、MOD_B.pm の中の use MOD_A; は
あってもなくても変わらない。
とりあえず、相互に use するような設計がおかしいので考え直せ。
0382nobodyさん
04/04/25 21:00ID:???HTMLでの " は \" になることは知っているので、そうしたのですが、
! や ? の記号の前にも \ が必要なのですか?それとも他の記号なのでしょうか?
0383nobodyさん
04/04/25 21:06ID:???話はそれからだ。
0384nobodyさん
04/04/25 22:15ID:???cgiで文字列の出力をしようとしているのですが、500エラーがでます。
" は \" になることは知っているので、そうしたのですが、
! や ? の記号の前にも \ が必要なのですか?それとも他の記号なのでしょうか?
0386nobodyさん
04/04/26 16:42ID:NLGfQi9Fディレクトリに、Basic認証もしくはDigest認証をかけて
/private/secure.cgi
へアクセスをした場合に、ユーザ名・パスワードを引数として
渡すには、どうやったら良いのでしょうか?
どなたかご教授、お願い致します。
0387nobodyさん
04/04/26 17:04ID:???パスワードを CGI に引き渡すのは
少なくとも現行の CGI というインタフェースを使う限りでは
原理的に不可能です。
これは Perl コーディング上の制限ではなく
CGI というインタフェース仕様上の制限です。
CGI 以外の方法なら、
例えば mod_perl を使って PerlAuthenHandler を組むやり方であれば
Apache Request オブジェクトの get_basic_auth_pw() メソッドを使って
パスワードを取得することができます。
0388386
04/04/26 17:18ID:NLGfQi9Fレスありがとうございます。
REMOTE_USERでのユーザ名引き渡し、確認できました。
パスワードはやはり無理ですか...
ユーザ名だけを利用して(重要な部分へは再認証という形で)
対応していきます。
0389nobodyさん
04/04/26 17:45ID:8MkOGNrLエラー処理ができなくて困っております。
例えば、
my $dbh = DBI->connect("dbi:Pg:dbname=$dbname;port=$port", $user, $password, {RaiseError => 1, AutoCommit => 0}) || print "error";
これで$dbnameが存在していないものを指定すると、printにいってくれず、
Internal Server Errorが出てしまいます。↓error_log
DBI connect('dbname=--;port=--','',...) failed: FATAL: database "--" does not exist at --.cgi line --
ご教授いただけませんでしょうか。
宜しくお願いします。
0391nobodyさん
04/04/26 18:11ID:???横槍入れるようだが、同じパスワードで何回認証しても意味ないと思うんだが。
ユーザー名は追跡の為に追うこともあるだろうけど。
0392nobodyさん
04/04/26 18:24ID:???ユーザ名とパスはリクエストヘッダAuthorizationで渡されるから拾えばいい。
例えば.htaccessで
RewriteEngine on
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule test.cgi test.cgi$1 [e=HTTP_CGI_AUTHORIZATION:%1]
($scheme, $data) = split (' ', $ENV{'HTTP_CGI_AUTHORIZATION'});
if ($scheme eq 'Basic') {
$data = &decode_base64 ($data);
($ENV{'REMOTE_USER'}, $ENV{'REMOTE_PASSWORD'}) = split(':', $data);
}
sub decode_base64 {
my ($str) = "@_";
my ($res, $len) = "";
local($^W) = 0;
$str =~ tr|A-Za-z0-9+=/||cd;
if length($str) % 4;
$str =~ s/=+$//;
$str =~ tr|A-Za-z0-9+/| -_|;
while ($str =~ /(.{1,60})/gs) {
$len = chr(32 + length($1)*3/4);
$res .= unpack("u", $len . $1 );
}
return ($res);
}
print "Content-type: text/html", "\n\n";
print "$ENV{'HTTP_CGI_AUTHORIZATION'}<br>\n";
print "$ENV{'REMOTE_USER'}<br>\n";
print "$ENV{'REMOTE_PASSWORD'}<br>\n";
0394nobodyさん
04/04/26 18:39ID:???ちょっと間違った
RewriteEngine on
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule test.cgi test.cgi [e=HTTP_CGI_AUTHORIZATION:%1]
sub decode_base64 {
my ($str) = "@_";
my ($res, $len) = "";
local($^W) = 0;
$str =~ tr|A-Za-z0-9+=/||cd;
$str =~ s/=+$//;
$str =~ tr|A-Za-z0-9+/| -_|;
while ($str =~ /(.{1,60})/gs) {
$len = chr(32 + length($1)*3/4);
$res .= unpack("u", $len . $1 );
}
return ($res);
}
0396nobodyさん
04/04/26 21:22ID:BWwI4BSicgiでcss文書を吐き出したいんですが、Content-type:text/cssと最初につけておけばよいのでしょうか?
infoseek iswebでこれをやると広告がついてきてcssとして使えなくなるんですが、普通にうpしたcssファイルはhttpでgetできます。
この差はCGI作り手側のミス?それとも拡張子cgi=広告付加とかCGI作り手側じゃどうしようもないものですか?
0397nobodyさん
04/04/26 21:28ID:???0399nobodyさん
04/04/26 23:30ID:???そうでしたか…失礼。
0400nobodyさん
04/04/27 17:46ID:m4JuDEBr0401nobodyさん
04/04/27 17:51ID:???0402nobodyさん
04/04/27 17:56ID:m4JuDEBrできるだけ早く処理できる方法があったらお願いします。
0403nobodyさん
04/04/27 18:04ID:???できるだけ待ち時間を短くするための工夫としては、
ソケットを non-blocking で開いて並列で処理する、ぐらいか。
0404nobodyさん
04/04/27 20:01ID:D2O5MFhmprint "content-type: text/html\n\n";
open(TEST, "sub/test.htm");
while (<TEST>) {
print $_ ;
}
close(TEST);
exit;
ローカルではうまくいくのですが、サーバーに上げて実行してみると上手くいきません。
0406nobodyさん
04/04/27 20:14ID:???それに「うまくいかない」で読んでるやつがどうなったかわかると思うか?
0407nobodyさん
04/04/27 22:30ID:???先頭にtime値を書き込んで、新しい方を読み,古い方に書く
2重ファイル方式を取入れたのですが、ログが消えた時はそのままでした。
flock考やperlメモのやり方でもたまに飛ぶので(ローカルでは書き込みプログラムを何個走らせても飛ばないんですが…)
バックアップ的にこのやり方を導入したいんですが、アドバイス願えないでしょうか?
0408nobodyさん
04/04/27 22:36ID:???並列で処理しないとロックの検証にはならないよ。
でなきゃ鯖の問題だな。
0409nobodyさん
04/04/27 22:55ID:???0410nobodyさん
04/04/27 23:00ID:???同じ値になるだろ
0411nobodyさん
04/04/27 23:01ID:???0412404
04/04/28 00:18ID:2okML1Hbですがまた問題が発生しました。
sub/test.htmから<n月>という文字列がある行をマッチさせたいのですが、下のようにすると
ローカルではマッチするんですが、サーバーに上げるとマッチせず。。。
print "content-type: text/html\n\n<html>";
open(TEST, "sub/test.htm");
while (<TEST>) {
if ($_ =~ /<.*?月>/) {print $_;}
}
close(TEST);
print "</html>";
exit;
4行目を
if ($_ =~ /<(.*?)月>/) {print $_;}
に書き換えるとローカルでもサーバーでもマッチします。なぜでしょうか。
■ このスレッドは過去ログ倉庫に格納されています