Perlコーディング初心者質問スレ Part 38
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
04/10/07 23:23:08ID:kiEzDCJF【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。
1: 自分はこういう事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。
過去ログやお勧めサイトは >>2-10
0532526
04/11/04 13:52:12ID:???0534nobodyさん
04/11/04 14:45:41ID:???0536nobodyさん
04/11/04 15:34:22ID:???「変数を」別のスクリプトに渡す
ということは、foo.cgi->Browser->bar.cgiの過程で
foo.cgiが出力した値をbar.cgiに渡したいということか?
0538nobodyさん
04/11/04 15:51:48ID:???海外で手に入れた会員管理の有料perlプログラムを使ってるんですが、
http://****.com/****.cgi?password=***** みたいな感じで
ログが残って、ログアウトしたあとも、ブラウザの戻るとかで
会員画面に入れるんだが、
詐欺プログラムですか、これは?
perlのことあまり詳しくありませんが、これなんとかする方法ありますか?
0540nobodyさん
04/11/04 16:03:30ID:???そういうセッション管理で一般的に使われるのはCookieだな。
Passは最初の認証だけ使って、後はセッションIDをCookieへ入れといて、
ワンタイムパスワードをPOSTさせて認証処理・・・って感じになるのかな。
本なんかをちょっと見ただけで実際に作ったこと無いから、落とし穴があるかも。
Cookieは気をつけないとPOST以上に危険だから注意
あと、
>ブラウザに丸見えになりますよね?
の一言が気になるんですが、まさかtype="hidden"を知らないなんてことは・・・
0541nobodyさん
04/11/04 22:34:38ID:???0542nobodyさん
04/11/05 00:12:53ID:???ActivePerl入れて、インターネットゾーンでも使えるようにレジストリ緩めれば、language=perlで好きなことできるよ。
そんな糞ページ誰も見ないがな。
0544nobodyさん
04/11/05 04:30:09ID:127p6d3j例:-a、-l、-h、-v、-r、<引数なし>を引数とする。
現在、引数を見て処理させる場合、
if ($#ARGV == "0") {
if ($ARGV[0] eq "-a") { 処理1; }
elsif ($ARGV[0] eq "-l") { 処理2; }
elsif ($ARGV[0] eq "-h") { 処理3; }
elsif ($ARGV[0] eq "-v") { 処理4; }
elsif ($ARGV[0] eq "-r") { 処理5; }
else { &error; }
}
elsif ($#ARGV == "1") {
if ($ARGV[0] eq "-a" && $ARGV eq "-l") { 処理5; }
elsif ($ARGV[0] eq "-l" && $ARGV eq "-h") { 処理6; }
elsif ($ARGV[0] eq "-h" && $ARGV eq "-v") { 処理7; }
elsif ($ARGV[0] eq "-v" && $ARGV eq "-r") { 処理8; }
elsif ($ARGV[0] eq "-r" && $ARGV eq "-a") { 処理9; }
else { &error; }
}
などとしていますが、引数が増えるとそれだけ組み合わせも増えるわけで
現在引数による分岐だけで混乱しています。しかもこのスクリプトを実際に
使用する場合、引数の順序も固定されてしまうので、表現力が乏しくなります。
それぞれの引数に数字を割り当てて、それをfor (@ARGV)で見ていって
それらを加算した結果で処理させる方法などを考えましたが、
数字を割り振るコツも分かりません。
引数や、それらの組み合わせが増えたとき、どういう風に対処すれば
分かりやすく、作りやすいスクリプトが書けるのでしょうか。
よろしくお願いします。
0545544
04/11/05 04:39:45ID:127p6d3j正しくは以下の通り。
if ($#ARGV == "0") {
if ($ARGV[0] eq "-a") { 処理1; }
elsif ($ARGV[0] eq "-l") { 処理2; }
elsif ($ARGV[0] eq "-h") { 処理3; }
elsif ($ARGV[0] eq "-v") { 処理4; }
elsif ($ARGV[0] eq "-r") { 処理5; }
else { &error; }
}
elsif ($#ARGV == "1") {
if ($ARGV[0] eq "-a" && $ARGV[1] eq "-l") { 処理5; }
elsif ($ARGV[0] eq "-l" && $ARGV[1] eq "-h") { 処理6; }
elsif ($ARGV[0] eq "-h" && $ARGV[1] eq "-v") { 処理7; }
elsif ($ARGV[0] eq "-v" && $ARGV[1] eq "-r") { 処理8; }
elsif ($ARGV[0] eq "-r" && $ARGV[1] eq "-a") { 処理9; }
else { &error; }
}
0546nobodyさん
04/11/05 04:46:45ID:???引数をハッシュに代入してexistsで条件分離したら?
for(@ARGV){
$param{$_} = '1'; #値自体はなんでもいい。
}
分岐は
if(exists $param{'-a'}){ 処理1;}
とか
if($param{'-a'} == 1){ 処理1;}
みたいの。
0547nobodyさん
04/11/05 06:55:34ID:???my %table = (
'a' => sub{ print "処理1" },
'l' => sub{ print "処理2" },
...
'r' => \&r_part,
'al' => \&r_part,
'hl' => sub{ print "処理6" },
...
);
sub r_part{ print "処理5" }
my $key = join('', sort @ARGV);
if (exists $table{$key}){
$table{$key}->();
} else {
print "ERROR";
}
0548547
04/11/05 07:02:16ID:???0549nobodyさん
04/11/05 07:51:54ID:???getoptとか、そんなのはダメ?
http://www.aplawrence.com/Unix/perlgetopts.html
0550544
04/11/05 10:39:14ID:T3r+ugEGありがとう御座います!
ぱっと見た感じでは
>>546さんと>>547さんは同じ処理ですか?
連想配列にこういう使い方があったと知って、眼から鱗の初心者です>私
両方を試してみます。ありがとうございます。
>>549
煩雑な徒手作業のところをできる限り自動化/半自動化していく積もりで
ゆくゆくはこうしたモジュールを有り難く使った方が効率が良いとは考え
ているのでこういう助言は本当に助かります。
ありがとうございます。
早速実験してみます。
ありがとう御座いました。
0551nobodyさん
04/11/05 11:05:29ID:vXdBVIeu正規表現で
s/ //g;
とやっても空白がマッチしなくなりました
s/\s//g;
ならマッチします
原因と元に戻す対処法を教えてください
0552551
04/11/05 11:19:18ID:vXdBVIeu0553nobodyさん
04/11/05 11:36:35ID:vAMAiFLGttp://tohoho.wakusei.ne.jp/wwwperl2.htm
こちらのsocket関数の項目に書かれているスクリプトを自分の
スクリプトに組み込んでますが
自分の使っているサーバーでperl -wcでスクリプトチェックを行ったら
Unquoted string "stdout" may clash with future reserved word at aaa.cgi line 543.
このような警告文が表示されました。
select(stdout);
のstdoutをAAAとか別のものに置き換えたらこの警告文が回避できましたが
別のものに置き換えても正常に動くのでしょうか?
perlのバージョンはThis is perl, v5.8.2 built for i386-freebsdです。
0554nobodyさん
04/11/05 11:56:32ID:???0555553
04/11/05 12:26:44ID:vAMAiFLGどうも有り難うございます。
stdoutをそのまま大文字にしても動くんですね
0556nobodyさん
04/11/05 13:45:35ID:uR92YhZOアドレス欄にIDとパスワードが表示され、
そのIDとパスワードを含んだアドレスを入力すると、
ログが記録されないのです。
(cgiの認証画面から入力するときちんと記録されます)
ログ記録はこんな感じなのですが。。。
どこか間違っているのでしょうか
sub record {
local($date,$time,$agent,@data);
# 時間&ホスト取得
$date = &get_time;
$time = time;
&get_host;
# ロック開始
&lock if ($lockkey);
# ログファイルの読み込み
open(IN,"$prvdir/$logfile") || &error("Open Error: $logfile");
@data = <IN>;
close(IN);
# ブラウザ情報
$agent = $ENV{'HTTP_USER_AGENT'};
$agent =~ s/&/&/g;
$agent =~ s/</</g;
$agent =~ s/>/>/g;
$agent =~ s/"/"/g;
0557556続き
04/11/05 13:45:59ID:uR92YhZO# ログ更新
while ($max <= @data) { pop(@data); }
unshift(@data,"$in{'id'}<>$date<>$host<>$agent<>$time<>\n");
open(OUT,">$prvdir/$logfile") || &error("Write Error: $logfile");
print OUT @data;
close(OUT);
# ロック解除
&unlock if ($lockkey);
}
0558556続き
04/11/05 13:54:30ID:uR92YhZOどなたか解る方お願い致します。
sub pwCheck {
local($f,$id,$pw,$check,$time);
if ($mode eq 'enter') {
$time = time;
if ($in{'cook'} eq "") { $in{'cook'} = 0; }
&set_cookie($in{'cook'}, $time);
}
$f=0;
open(IN,"$prvdir/$pwdfile") || &error("Open Error: $pwdfile");
while (<IN>) {
($id,$pw) = split(/:/);
if ($in{'id'} eq $id) { $f++; last; }
}
close(IN);
if (!$f) { &error("認証できません"); }
$pw =~ s/\n//;
$check = &decrypt($in{'pw'}, $pw);
if ($check != 1) { &error("認証できません"); }
&fileOpen;
if ($mode eq 'enter') { &record; }
exit;
}
0559nobodyさん
04/11/05 14:09:48ID:???0560nobodyさん
04/11/05 15:14:14ID:???まず、メソッドについて勉強したら良いんでないかい?
http://www.google.com/search?num=100&hl=ja&inlang=ja&safe=off&c2coff=1&q=GET+POST+%24ENV%7B%27REQUEST_METHOD%27%7D&lr=lang_ja
0561nobodyさん
04/11/05 15:21:59ID:???何をしたくて、どこがどのように思った通りに動いてくれないのか
わからない…。
URLにクエリーが表示されちゃって困ったよー。って話じゃない…?
0562nobodyさん
04/11/05 16:10:54ID:???0563伊藤
04/11/05 17:14:02ID:???0564nobodyさん
04/11/05 21:03:45ID:w/zBhN/Xこれを新しいウィンドウで開きたい場合はどのように書き直せばいいのでしょうか?
以下のようにするとエラーなんです。
よろしくお願いします。
print " <a href=\"$script?action=icondisp&type=$FORM{'type'}\" target="_blank">$lbl_iconlist</a>\n";
0565nobodyさん
04/11/05 21:17:13ID:???バーカ
print ' <a href="' . $script . '?action=icondisp&type=' . $FORM{'type'} . '" target="_blank">' . $lbl_iconlist . '</a>' . "\n";
0566nobodyさん
04/11/05 21:38:56ID:w/zBhN/X全角にスペースにしわすれました
すいません
0567nobodyさん
04/11/05 22:58:07ID:???printf qq| <a href="%s?action=icondisp&type=%s" target="_blank">%s</a>\n|;
$script, # スクリプトのお名前
$FORM{'type'}, # typeの値
$lbl_iconlist; # アイコソリスト(文字列)
0568nobodyさん
04/11/05 22:58:54ID:???あらやだ。
> printf qq| <a href="%s?action=icondisp&type=%s" target="_blank">%s</a>\n|;
printf qq| <a href="%s?action=icondisp&type=%s" target="_blank">%s</a>\n|,
0569365
04/11/05 23:36:15ID:???でいいんじゃないの?
0570nobodyさん
04/11/06 02:52:14ID:???0572nobodyさん
04/11/06 09:00:12ID:???0573nobodyさん
04/11/06 10:24:21ID:???0574nobodyさん
04/11/06 14:55:07ID:???ところで、NullPointerExceptionをPerl語にすると何?
0575nobodyさん
04/11/06 16:06:17ID:???0576nobodyさん
04/11/06 16:06:35ID:???0577nobodyさん
04/11/06 17:29:59ID:???ブラウザにファイルの内容を送ろうと思うのですが,どうすれば良いでしょうか?
以下だとファイルが壊れてしまいます.
open(FILE,"$FileName");
binmode(FILE);
print <FILE>; ←while(<FILE>){print $_ }でもだめ.
close(FILE);
送りたいファイルは40KB程度ですが,数MB程度のファイルも対応できるとうれしいです.
お知恵をお貸しくださいm(_ _)m
0578577
04/11/06 17:41:38ID:???よろしくお願いします.
0579nobodyさん
04/11/06 17:53:55ID:???環境によっては binmode(STDOUT); がいるんじゃないかな。
あと、バイナリファイルなら行読み込みにせず、readでバイト数指定して読み込み
while (read(FILE, $buffer, 1024*10)) ... バッファサイズは適当に
printで出力する場合はバッファoffするのも忘れずに $|=1 (念の為
0580nobodyさん
04/11/06 17:58:03ID:???binmode(STDOUT) してないだけじゃないの?
つーか、壊れるという曖昧な表現じゃなくて
バイナリエディタで比較してみたら こういう違いがでてきた、ってな感じで話してくれないと。
まぁ、それ見りゃ自分でもおかしいとこに気づくんだろうけどね
0581580
04/11/06 17:59:28ID:???カコワリィ
0582577
04/11/06 18:12:10ID:???レスありがとうございました。
原因は二つで,binmode(STDOUT)されてないこと,行読みした結果,改行コードが欠落したことでした.
>>579
「$|」というのはPerlの環境変数のようなものなのでしょうか?
print $|;だと値を返すようですが・・・
手元の資料&Google先生を調べても分からなかったのですorz
>>580
ご指摘,ありがとうございます.
「どういう風に壊れたのか」を説明する必要がありました.
失礼しました.
0583nobodyさん
04/11/06 19:13:15ID:???Don't mind, 既知問題っぽかったから推測で書いちゃったけど
実は全然違う原因だったって事はよくあるからね.
>>582
$|は検索しにくいのが難点だな。Perl バッファリングで調べると詳細でてくるよ。
0585nobodyさん
04/11/06 20:47:26ID:55uCUnw3/ ̄'☆ )>>1
/ > /
☆をダブルクリックするとかめはめ波が出るぞ
注)設定とか環境のせいで正常にかめはめ波しないときがあります
0587nobodyさん
04/11/06 20:56:12ID:ZyicEXrdを実行すると、「p.tif」 のファイル名が文字化けしてしまいます。
「use encoding "shift_jis";」の行を外すと、正常に「あ.tif」に変換
されるのですが、この行を残したままrename するにはどうすれば
よろしいでしょうか?
use encoding "shift_jis";
chdir 'c:\\test';
rename "p.tif", "あ.tif";
0588nobodyさん
04/11/06 21:13:32ID:jPPLQ8mN/ ̄'☆ )>>587
/ > /
☆をダブルクリックするとかめはめ波が出るぞ!
注)設定とか環境のせいで正常にかめはめ波しないときがあります
0589nobodyさん
04/11/06 21:20:51ID:???iso-2022-jp|shift-jis|euc-jp|multipart\/mixed
という記述をします。これを応用して、『英語か日本語にマッチ』するかどうかを記述するには
どうすればよいでしょうか?
0590587
04/11/06 22:56:11ID:???よろしくお願いします。
use encoding "shift_jis";
use Encode;
chdir 'c:\\test';
$str = encode("shiftjis","あ.tif");
rename "p.tif", $str;
0591nobodyさん
04/11/06 23:23:01ID:???no encoding;
で一旦切ってしまって、処理後にもう一度
use encoding "shift_jis";
しておく…のはあまりスマートじゃないですね。。
>>589
「キャラクタセットが英語または日本語である場合マッチ」ということなら、
http://www.iana.org/assignments/character-sets
↑と睨めっこして、必要なのを足していくとか。
(キャラクタセットの指定が無かったり、Unicodeを使われたら、終わりな気もするけど。)
0592nobodyさん
04/11/07 19:03:48ID:???する方法をど忘れしてしまったので教えてください。
「#」じゃなく。
0593592
04/11/07 19:14:26ID:???=comment # ここからコメント
=cut # ここまでコメント
0594nobodyさん
04/11/07 19:14:34ID:???0595nobodyさん
04/11/07 20:51:25ID:OKDqn1bD@dat = split(/*/, <DAT>);
これで合ってると思うのですが、どうしてもエラーになってしまいます。
*DATは存在します。ちゃんと*で区切られています。
0596nobodyさん
04/11/07 20:53:39ID:???0597nobodyさん
04/11/07 20:54:42ID:V/bBugXz誰かお願いします。
文字列 $xx=あいうえおaiueo
から2番目の'い'を取り出だすとき
substr($xx,1,1);ではだめで
全角は2バイト分なので
substr($xx,3,2);でないとだめなようです。
0599597
04/11/07 21:00:05ID:V/bBugXzランダムに生成された全角半角混合の文字列
$xx=げあじgraふぇeあefaじえeaあい;
から9番目のeを取り出す方法を教えて
0601nobodyさん
04/11/07 22:01:19ID:???0602nobodyさん
04/11/07 22:03:13ID:???my @moji;
foreach ($xx =~ /[\x81-\x9f\xe0-\xfc][\x40-\x7e\x80-\xfc]|[\x20-\x7e\xa0-\xdf]/g) {push (@moji,$_)}
print $moji[8];
0603nobodyさん
04/11/07 22:40:30ID:???そこまでやったら、直接取り出せばいいんじゃない?
my $p = 9;
my ($moji) = ($xx =~ /([\x81-\x9f\xe0-\xfc][\x40-\x7e\x80-\xfc]|[\x20-\x7e\xa0-\xdf]){$p}/);
print $moji;
お勧めは、version5.8以上なら>>600さんの通りEncodeで、
それ未満なら、
http://search.cpan.org/~sadahiro/String-Multibyte-1.05/Multibyte.pm
0604nobodyさん
04/11/08 00:46:30ID:???my @moji = ($xx =~ /[\x81-\x9f\xe0-\xfc][\x40-\x7e\x80-\xfc]|[\x20-\x7e\xa0-\xdf]/g);
print @moji[2..8];
なんにせよ環境も要件もよくわからんと返しようがないのぉ。
0605597
04/11/08 02:03:34ID:???トリップ生成用途だったのですが、これでうまくいきそうです。
みなさんどうもありがとうございます。
0607595
04/11/08 11:09:36ID:IV2+5aK4で代入したら、$data[0]にしか代入されていません。
どなたかよろしくお願いします。
0608nobodyさん
04/11/08 12:07:11ID:???その場合の <DAT> は一行しか読み込まないので、当然そうなるだろう。
というか何がしたいのだいったい。
ひょっとして君のやりたいことは @data = <DAT> だったりしないか。
0609nobodyさん
04/11/08 13:34:38ID:???0610595
04/11/08 15:22:15ID:hLOeveWjあっ、すみません。<DAT>はファイルハンドルです。
>>608
なぜこの場合だと一行しか読み込まないのですか?
では、どうすればすべての行を読み込んでくれますか?
説明不足ですみません。返答お願いします。
0612595
04/11/08 16:59:14ID:x02iMqC5すみません。やっていることがおかしかったですね。
ありがとうございました。
0613nobodyさん
04/11/08 17:06:22ID:???http://www98.sakura.ne.jp/~jun/perl/
どなたかここの移転先を知りませんか?
Perlに関するTipsや排他制御について、リファレンスについて説明してあったサイトなのですが
何時の間にかなくなったようで、、、、
0614nobodyさん
04/11/08 17:17:29ID:???閉鎖したんじゃないですかね?
どうしても見たいなら
ttp://web.archive.org/
でも使って下さい。
0615nobodyさん
04/11/08 21:29:51ID:???とすると改行\nが消えないですが、それを消して配列に代入する方法はありませんか。
0616nobodyさん
04/11/08 21:45:10ID:???0617nobodyさん
04/11/08 21:57:37ID:???{ local $/ = undef; @var = split(/\n/, <IN>); }
あたりかな。ただしファイルの末尾の空行が消えるのが嫌なら、
splitの第3引数に負の値を与えるとともに、splitしたあとで
@varの最後の要素を捨てる必要があるだろう。
普通に読んだ後でchomp @varした方が書くのは楽だね。
0618nobodyさん
04/11/08 22:31:46ID:???0619nobodyさん
04/11/09 00:16:14ID:???これを回避するにはいちいちヒアドキュメントを閉じるしかないですか?
0620nobodyさん
04/11/09 00:47:01ID:???0623nobodyさん
04/11/09 06:54:36ID:???このスレで質問するとよく言われます。。
>617>618
ありがとうございます。
0624nobodyさん
04/11/09 07:22:29ID:???言われないように努力したりしないの?
釣りだと思われるような質問しちゃってるんだよ?
0625nobodyさん
04/11/09 07:43:45ID:???例えばWindowsで下を実行すると
print $^O
> MSWin32
とか出ますが,WinXPとかWin98とかくらいまで詳しく知るには,どういう方法がありますか。
(できればUnix系でも詳しく知りたいです)
0626nobodyさん
04/11/09 09:36:25ID:enWymUQXされていないかとかしたいのですが、どうやってやったらいいのでしょう?
$url = "http://www.example.com/file.jpg";
@data = stat $url;
とかやっても取れないので(うすうすわかっていましたが)。。。
ウェブ上のデータとstatの内容を取得する方法を教えてください。
0627nobodyさん
04/11/09 09:59:56ID:???lwpでもなんでもいいけど
httpのヘッダで
Date か Last-Modified みるしかなかんべ。
取れなかったら諦めるしかない。
0628nobodyさん
04/11/09 10:07:38ID:enWymUQXありがとう。
そういうものなんですか。
0629nobodyさん
04/11/09 18:49:56ID:???$hoge =`uname -m`; とか。
詳しいことはUNIXのコマンドリファレンスでも探せば良し。
>>626
他のサーバーのデータは、
socketでソケット作って、connectで繋いで初めて得られる。
色々複雑だから、素直に解説本読みなはれ。
0630nobodyさん
04/11/09 19:46:44ID:???http://aspn.activestate.com/ASPN/docs/ActivePerl/lib/Win32.html
use Win32;
print join(', ', Win32::GetOSVersion()), "\n";
print join(', ', Win32::GetOSName()), "\n";
0631nobodyさん
04/11/09 22:34:49ID:???ありがとうございます。こんな風にしていろいろな環境でOS名を取得できました。
# 自分の目的のためには下の例で事が済んだのですが。
#-------
my $OS;
if ( $OS = `uname -s` ) {
#do nothing
} elsif ( !$OS and eval{require Win32} ) {
$OS = ( Win32::GetOSName() )[0];
} else {
die "MacPerl?";
}
print $OS;
> Linux, FreeBSD, Win2000, Win98...
#-------
my $OS = $^O;
if ( $OS eq 'MSWin32' ) {
require Win32;
$OS = ( Win32::GetOSName() )[0];
}
print $OS;
> linux, freebsd, Win2000, Win98...
■ このスレッドは過去ログ倉庫に格納されています