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

Perlコーディング初心者質問スレ Part 40

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん05/01/27 18:08:42ID:???
Perlのコーディングで困ってる人のスレです。

【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。

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

最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。

過去ログやお勧めサイトは >>2-10
0581nobodyさん05/02/21 19:51:45ID:???
>>567
, は、リスト評価。 . は、文字列を結合してからスカラー評価。
, と . では、演算子の優先順位が違うので、計算式が入る場合は注意。

>>577
print join( '-', split( '_', $value ) );
とか
print "$1-$2-$3" if $value =~/([^_]+)_([^_]+)_([^_]+)/;
とか
0582nobodyさん05/02/21 19:55:47ID:???
>>578
use strict; すれば?
sub の中の$valueは、undefだよ。
0583nobodyさん05/02/21 20:08:42ID:???
>>577
my $value = 'oaoa_aaaa_test';

(my $tmp = $value) =~ tr/_/-/;
print "$value => $tmp\n";

sub _toh { (my $str = shift) =~ tr/_/-/; $str }
print "$value => ${\_toh($value)}\n";

print join '-', split '_', $value;

print "$value => ${\ (sub { (my $str = shift) =~ tr/_/-/; $str })->($value) }\n";

local $" = '';
print "$value => @{[ map { tr/_/-/; $_ } split //, $value ]}\n";
0584nobodyさん05/02/21 20:11:04ID:???
>>578
デリファレンスする前にリファレンス取らないと、シンボリックリファレンスになる。
0585nobodyさん05/02/21 20:12:54ID:???
>>580
http://www.din.or.jp/~ohzaki/perl.htm#CRLF_Unify
0586nobodyさん05/02/21 20:37:31ID:???
>>576-578
@_ は関数内で暗黙のlocalだけど、@_の各要素である$_[0],$_[1],...等は、
呼出し元の引数の別名だから、上書きすると、呼び出し元で引き数として渡した
対応する変数の中身が書き変るよ。

好きなのどうぞ

print qq|${\sub{$_[0]->[0] =~ s/_/-/g;$_[0]->[0]}->([$value])}あいうえお|;

print qq|${\map{$_->[0] =~ s/_/-/g;$_->[0]}[$value]}あいうえお|;

print qq|${\do{(local $_=$value) =~ s/_/-/g;$_}}あいうえお|;
0587nobodyさん05/02/21 21:46:42ID:LbE3SevL
サブルーチンがハッシュのリファレンスを2つ返してきます。
それをデリファレンスしながら受け取りたいんですが不可能ですか?

my (%a,%b) = map{%{$_}}&hoge;

こんなことを考えてみたけど、よく考えたら全くダメだった;
0588nobodyさん05/02/21 21:49:32ID:???
Can't find string terminator "^@" anywhere before EOF at C:\Program Files\Apache
Group\Apache\htdocs\test.cgi line 353.

こんなエラー内容なんだけど、誰かわかる?
^@こんな文字列検索しても出てこないんだよね。ライン付近を見ても異常が見当たらない。
0589nobodyさん05/02/21 21:51:30ID:???
;が抜けてるとか
0590nobodyさん05/02/21 21:56:01ID:Mewlqio0
^@ は、文字コード0だろ?
059158705/02/21 22:15:40ID:LbE3SevL
do{sub{%a = %{shift()}; %b = %{shift()}}->(&hoge)};

これで一応できました^^
0592nobodyさん05/02/21 22:50:15ID:???
>>585
ありがとうございました。できました。
0593nobodyさん05/02/21 23:42:47ID:???
>>591
ほんとはこういう必殺技があるんだけど型グロブが理解できなければ使わないほうがいい。

(*a,*b) = hoge();
0594nobodyさん05/02/22 11:45:02ID:???
変数の計算について質問

いきなり
my %a;
for (1..10){
$a{a} += 2;
}

とかやっても失敗しなかったのですが、偶然ですか?
my %a = (a => 0);
とはじめにしておいたほうが当然無難でしょうけど、なんか面倒なんですよね。

面倒でもやっておかないと失敗することはあるんでしょうか?
0595nobodyさん05/02/22 12:06:49ID:xOztdvV5
八代空きじゃなくて、
よし行く象を最後にすべきだろう
0596nobodyさん05/02/22 12:07:19ID:???
↑ああああああああああああ、激しくmiss m(_ _)m
0597nobodyさん05/02/22 13:16:01ID:???
>>594
未定義値を論理評価すると偽として解釈される。
未定義値を数値評価すると0として解釈される。
未定義値を文字列評価するとヌル文字列として解釈される。
未定義値の配列やハッシュは空要素として解釈される。
配列やハッシュの存在しない要素を参照すると値は未定義値である。
my指定した変数は、明示的に初期化しなければ未定義値で初期化されることが保証されている。

これを理解していれば>>594の場合で明示的に初期化する必要はない。
0598nobodyさん05/02/22 14:13:34ID:cioenldL

my %hash = ( a => 1 , b => {c => 1} );
&test({ b => {%{$hash{b}}} });
sub test{
my %hash = %{$_[0]->{b}};
$hash{c}++;
print $hash{c},"<br>";
}
print $hash{b}->{c};

これリファレンスの仕組みを理解するのに書いたんですが、
グローバルな$hash{b}にはハッシュリファレンスが入ってます。
それをルーチンに渡す時にそのまま渡すとルーチンないの作業によっては
グローバルな変数の中身に影響がでますよね。
そのため今までは
&test({
b=>{%{$hash{b}}}
});
としていました。しかしb=>\%{$hash{b}}でやっても何故かルーチンないでの作業が
グローバル側に影響を及ぼすことはありませんでした。

どうしてなのでしょうか?
jcodeなどに代表されるように通常は\これで作ったリファレンスを渡すと渡し側のものを
直接いじるのと同じ行為になると思ってたのですが・・・

ハッシュの場合は違うのか、それともデリファレンスしたものだから違うのかな?
0599nobodyさん05/02/22 15:56:51ID:???
>>598
my %hash = %{$_[0]->{b}};

で新しく作った%hashにコピーされてるから、

$hash{c}++;

はコピーされた方が変わるだけ。

元のプログラム全体については何をしたいのか意図がよくわからんので、
エスパー回答者にお任せします。
060059805/02/22 17:37:34ID:cioenldL
>>599
そういえばそうですね;
ではやはり\を使って渡すのは危ないということですね。

元のプログラムはたんなるリファレンスのテストです。
0601nobodyさん05/02/22 17:44:16ID:???
ポートチェックのスクリプトを書いたのですか上手く動作しません
おかしなところがあったら教えてください
メイン
#!/usr/bin/perl
@port = (80,1080,3128,8000,8080,8888); # チェックするポート番号

PrinthtmlHeader(); #htmlのヘッダーと<BODY>まで出力する関数

foreach(@port){
$result=IsOpenPort($_);
print $result;
}

PrinthtmlFooter(); #htmlフッタ出力

exit;
0602nobodyさん05/02/22 17:45:28ID:iWUZ4gT8
#---------ポートが開いていれば1を返す関数
sub IsOpenPort
{
my ($port) = @_;
my ($inad,$scad);

eval{
$SIG{'ALRM'} = "hAlarm"; # ハンドラ設定
alarm(5); # timeout5秒に

use Socket;
socket(SOCK,PF_INET,SOCK_STREAM,0) || die("Socket Error\n");
$inad = inet_aton($ENV{'REMOTE_ADDR'}) || die("Iaddr Error\n");
$scad = pack_sockaddr_in($port, $inad);
connect(SOCK, $scad) || die("Connect Error\n");
select(SOCK);
$|=1;
select(STDOUT);
die("OUT!!!\n");
close(SOCK);
alarm(0);
};

if ($@ =~ /OUT/){ return 1; }
else{ return 0; }
}

#---------アラームシグナルハンドラ
sub hAlarm
{
die("Alarm...\n");
}
060360105/02/22 17:48:44ID:???
このスクリプトをレンタル鯖にアップロードしてたとえば
usen-219x123x129x154.ap-us.usen.ad.jp:3128
この串でアクセスしてみると
001000
と出力されれば正常なのですが
100000と出力されます
proxy.or3.marketscore.com:8000
この串でも100000と出力されます
0604nobodyさん05/02/22 18:16:06ID:???
>>601
まず結果を1と0に丸めるのをやめて、だめな時はどこで
ひっかかってるかをきちんと調べるところからはじめる
べきだな。あとシステムコール類がエラーしたときは
ちゃんと$!を表示すること。

具体的にどこでどういう状況になってるかを特定してから
出直してください。

0605nobodyさん05/02/22 19:28:41ID:???
>>598
# 呼び出し元をわざと中間変数を使って分解してみよう!

my %hash_c = ( c => 1 );
my %hash = ( a => 1, b => \%hash_c );

my %hash_b = %{$hash{b}}; # %hash_b = %hash_c; (1)
my %hash_arg = ( b => \%hash_b );
&test( \%hash_arg );

# つぎにsub test()を中間変数を使って分解してみよう!

sub test{
my $arg = $_[0]; # $arg = \%hash_arg;
my %hash = %{ $arg->{b} }; # %hash = %{ $hash_arg{b} }; --> %hash = %hash_b; (2)

$hash{c}++;
print $hash{c},"<br>";
}

# サブルーチンに引数を渡す前(1)も、渡した後(2)もコピーになってるでしょ。
# 呼出し元の%hashのリファレンスは、なにも渡ってないってことね。
0606nobodyさん05/02/22 23:11:35ID:???
ポルトガル語ある文章の中から、ある単語が含まれる文を抜き出す、といスクリプトを作りたいのですが、
/\b$hoge\b/
とやると、
$hoge = a の時だと
a~no や hu~a 等を含む文も引っかかってしまい、
$hoge = trouvero~ の場合
逆にどの文も引っかかってくれなかったりしてしまいます。

\bの仕様上、仕方ないのかもしれませんが、何か巧い方法はないでしょうか?
0607nobodyさん05/02/22 23:19:59ID:???
\bを使わない
0608nobodyさん05/02/22 23:40:27ID:???
>>606
ほい。

/^$hoge[^a-zA-Z\d~]|[^a-zA-Z\d~]$hoge[^a-zA-Z\d~]|[^a-zA-Z\d~]$hoge$|^$hoge$/

ただ、このやりかたはバックトラックが発生するからこっちがいいかもしれん

/^$hoge[^a-zA-Z\d~]/ || /[^a-zA-Z\d~]$hoge[^a-zA-Z\d~]/ || /[^a-zA-Z\d~]$hoge$/ || /^$hoge$/
0609nobodyさん05/02/22 23:47:16ID:???
>>>606
ポルトガル語に使う文字を定義して、?<!と?!を使うとか。

my $portuguese = "[a-z~]";
print "sim" if ($str =~ /(?<!$portuguese)$hoge(?!$portuguese)/i);
0610nobodyさん05/02/22 23:54:15ID:???
/(?:^|[^a-zA-Z\d~])$hoge(?![a-zA-Z\d~])/
でよさげ。
0611nobodyさん05/02/23 00:48:31ID:???
>607-610
ありがとうございました。
なんとか形にすることができました。

初めてperlに触れてみましたが、正規表現とかややこしいですね。
精進します。
0612nobodyさん05/02/23 10:07:36ID:???
2つの配列を両方同時に1つずつ取り出して処理したいのですが、Perlではそういうのは
できないのでしょうか?

print map "$_[0] + $_[1] = ",
@a
@b
こういうときにやりたいのですがl
0613nobodyさん05/02/23 10:37:22ID:???
print qq|
@{[sub{my $str = shift; $str =~ s/\r\n|\r|\n/<br>/g; $str }->($form{test})]}
|;

こういうことがしたいのですがエラーになりました。
原因は|です。qq[]などでやれば問題ないのですが、そうはしたくありません。
大元を変えると他にも影響がでそうなので;

qq||のなかの正規表現でor演算子的に|を使うにはどうすればいいでしょうか?
0614nobodyさん05/02/23 10:39:45ID:???
よくわからんけど。

二つでいいならハッシュにしたり。

それ以上の複数なら
for(my $count = 0; $count < ?? ; $count++){
$a[$count], $b[$count], $c[$count];
}
とか?

mapは無理だけど、自分でそんな関数は作れる。

sub (&\@\@){
my $code = shift;
my $a = shift; #ん?大丈夫かこれ??
my $b = shift;
@a = @$a;
@b = @$b;
for(なんたらかんたら;略;略){ #使用の詳細が不明なので略
  略;
}
}

みたいなイメージで。
0615nobodyさん05/02/23 10:44:07ID:???
>>614 なんか粗悪な記述でごめそ。

>>613
>大元を変えると他にも影響がでそうなので;
いみふ(ry
perlは処理の優先的にまず、区切り文字を探します。
0616nobodyさん05/02/23 12:39:44ID:???
>>613
不可能
無理
だめ
ばか
あほ
0617nobodyさん05/02/23 13:04:52ID:???
DBIを使ってmysqlからクエリを取り出す部分で問題が発生。
$sth = $dbh->prepare(q|select * from test_table where hoge=1|);
$sth->execute;
こういうSQL文を発行して

%hash = %{$sth->fetchrow_hashref};
これでそのレコードの全コラムを取得しようと思ったのです。

しかしwhereで引っかかるのがないときに、
%hash = %{$sth->fetchrow_hashref};
これがエラーの原因になります。

DBIはmysqlから「Empty set」を返された時にはfetchrow_hashrefに何も入れないのでしょうか?
それとEmpty setが返されたのかを知るすべはありますか?
0618nobodyさん05/02/23 13:49:08ID:???
>>613
ほれ!

print qq|
@{[sub{my $str = shift; eval qq[\$str =~ s/\\r\\n\|\\r\|\\n/<br>/g]; $str }->($form{test})]}
|;
0619nobodyさん05/02/23 13:53:36ID:???
>>612
ほれ!

@hoge = sub{map{$_[0]->(map{shift@$_}@_[1..$#_])}0..$#{(sort{@$b<=>@$a}@_[1..$#_])[0]}}->( sub{$_[0]+$_[1]+$_[2]}, [@x], [@y], [@z] );
0620nobodyさん05/02/23 13:58:20ID:???
>>618
お前はシングルクォートを知らんのか!
0621nobodyさん05/02/23 13:59:53ID:???
>>619
汚いソースを書くな!
0622nobodyさん05/02/23 14:01:11ID:???
>>618と>>619は、できないことはないけど、可読性が失われるという見本。
よくつかう処理はサブルーチンを用意すること。

変数展開の技巧や無名サブルーチンやリスト関数の技巧などは、理解できない内は使わない。
素直に書いた方が簡単な場合もある。
ただ、知ってて使う分には止めない。
0623nobodyさん05/02/23 14:04:13ID:???
>>621,620
おっとすまん、俺>>622=618=619なんだけど、皮肉で書いただけだから。
0624nobodyさん05/02/23 14:56:16ID:???
>>614を具現化

sub amap(&@){
my $code = shift;
my @array_ref_list = @_;

@array_ref_list = sort{@$b <=> @$a} @array_ref_list;
my $max_num = @{$array_ref_list[0]};

my @result_list;
for(my $i=0; $i<$max_num; $i++){

my @arg_list;
foreach my $a_ref(@array_ref_list){
push @arg_list, $a_ref->[$i];
}

my $result = $code->( @arg_list );
push @result_list, $result;
}

return @result_list;
}

@x = map{$_*1}1..10;
@y = map{$_*10}1..9;
@z = map{$_*100}1..5;

@hoge1 = amap{ $_[0]+$_[1]+$_[2] } \@x, \@y, \@z;
@hoge2 = amap{ 2*($_[0]-$_[1]) } \@z, \@y;
@hoge3 = amap{ $_[1].$_[0].$_[1] } ['a'..'z'], [reverse 'A'..'Z'];
062561705/02/23 15:04:23ID:???
できました。
excuteの返りを変数に代入して、その帰りが0ならって感じでした。
0626nobodyさん05/02/23 15:58:49ID:???
>>613
マジレスするとこうやね。

print qq|
@{[sub{my $str = shift; $str =~ s/\r\n\|\r\|\n/<br>/g; $str }->($form{test})]}
|;

ダブルクォート内のブロック処理は、ブロック内がコンパイルされる前に終端文字のエスケープだけ解除されるから
ブロック内の処理に終端文字が出てくるときは、'\' で普通にエスケープすればよい。

だからこんなこともできる。

print qq|
@{[sub{my $str = shift; $str =~ s/\r\n\|\r\|\n/<br>/g; qq\|<!--$str-->\| }->($form{test})]}
|;

もちろん読みにくいから終端文字を変えるなり、ヒアドキュメントを使うなりするのがいい。
0627nobodyさん05/02/23 16:00:36ID:???
sendmailが入ってないサーバでは絶対メール送信できないんですか?
何とかしてメール送りたいんですが・・・
0628nobodyさん05/02/23 16:09:38ID:???
>>627
Perl なら Net::SMTP モジュールを入れることで sendmail が無くてもメール送れる。
モジュールが使えない場合でも、
自分で SMTP 喋るようなスクリプトを Socket 使って書けば、メール送れる。

ただしサーバの出のポートが閉じてる場合は何やっても無駄だがな。
062962705/02/23 16:19:45ID:???
>>628
マジですか!?ちょっと調べてみます
サーバのポートが開いてるかどうかってのはどうやったら分かるんですか?
0630nobodyさん05/02/23 18:32:31ID:8RQQ1GXE
フォームメールCGIを作ってみたいんですが、エスケープしなければいけない文字や
その辺りの知識が足りません。

それで、とりあえず誰かが作ったエスケープが既にしっかりできてるCGIを見て
勉強しようと思います。

ちゃんとエスケープができてるものって探しようもないので、そこらへんを理解してる方で、
これなら勉強にもってこいってcgIを教えてくださいm(_ _)m
0631nobodyさん05/02/23 18:39:39ID:???
>>630
http://www.google.co.jp/search?hl=ja&inlang=ja&q=perl+%E3%82%A8%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%97&btnG=Google+%E6%A4%9C%E7%B4%A2&lr=
0632nobodyさん05/02/23 19:00:23ID:???
>>629
そのポート番号がどーなってるのか管理者に聞けばいいじゃん?
0633未承諾広告※ ◆TWARamEjuA 05/02/23 20:27:19ID:???
printf qq|<p><em>%s = %s</em>%s[%s]</p>\n|,
 eval {
  my @ret_value;
  :
  :
  return @ret_value;
 };

こういう書き方はよくするけれども、、、
0634nobodyさん05/02/23 21:10:15ID:???
sock(HOGE, &AF_INET, &SOCK_STREAM, $protocol);
これなんですけど、&をつける場合とつけない場合の
違いが分かりません。でも、結局&をつけた場合とつけない場合
をprintで調べたら同じ値なのにどうして、&をつけるタイプの人と
つけないタイプの人がいるのか分かりません。
何か&に特別な意味はあるんでしょうか?
0635nobodyさん05/02/23 21:29:59ID:???
>>612
print map{ "$a[$_]+$b[$_]=" } (0..$#a);

>>634
内部的に
sub AF_INET(){ 2 };
こんな感じで定義されていると思ってちゃぶ台。
だから、
print AF_INET();
print &AF_INET;
でもOK。
0636nobodyさん05/02/23 22:02:14ID:???
>635
どうも、返答ありがとうございました。
AF_INETって定数じゃなくてサブルーチンだったんですか。
なるほど。よく分かりました。
063763005/02/24 10:32:12ID:Q/hMlpe6
>>631
???
どういう意味ですか?

私はHTMLレベルのエスケープなんて聞いてませんよ。
それともフォームメールに必要なエスケープがHTMLレベルだとでも思ってるのでしょうか。
0638nobodyさん05/02/24 10:59:43ID:???
今までずっとプログラム内で必要なテキストや設定をtxtファイルにcsvもどき
や特殊な書式で書いてました。

しかしそれだと私しか理解できず、他人に使わせるのにいちいち書式のマニュアルを作成しないと
いけませんので、こんど全てをメジャーなものに変えようと思います。

一番いいのはexcelのcsv形式かなと思うのですが、どうですか?
ほとんどexcelを触ったことないので、いわゆるHTMLのthにあたるものができるのか
わからないのでまだ微妙ですが。

アドバイスお願いします。
0639nobodyさん 05/02/24 11:03:35ID:???
>>637
テメぇが聞きたいことなんか知ったこっちゃ無いし、聞き直してもえらそうだから教えてやんね。
0640nobodyさん05/02/24 11:04:06ID:???
まあ今から新しく作るなら XML かなと思う
Tomcat の設定ファイルみたいな感じで
0641nobodyさん05/02/24 11:05:15ID:???
>>637
「スレ違いだから自分でググって調べなさい」という皮肉だね、たぶん。
Perlのコーディングに直接にはなんの関係もない話をレスしないでねって暗に言っていると察っするが吉。
064263005/02/24 11:40:08ID:Q/hMlpe6
つまりフォームメールもまともに作れない回答者しかここにはいないってことか
さすがにここまで見当違いなレスをされるとあきれるね。

>>639
用がないならレスはしないでいいよ。暇だからって八つ当たりはやめとけ。

>>641
そうなんですかね。多分>>631は問題が何か理解できなかっただけでしょ。
HTMLレベルで考えてるとしか思えないね。
064363805/02/24 11:43:40ID:???
text::csv_xsを使ってみたんですが、素朴な疑問が;

何故かShift_JISのファイルをそのままパースできてるみたいですが、
これってEUCでもいいんですよね?

一応csvファイル事態はShift_JISですが、読み込んだときにEUCに変換して扱いたいんです。
パースして$csv->fieldsでとる前に変換はしておいたほうが回数も少なくて済みますし。

書き込み時には又、Shift_JISにしますけど。
064463105/02/24 11:45:55ID:???
あれだけでそんな判断するとはw
   \  __  /
   _ (m) _ピコーン
      |ミ|
     ('A`)    体技:スルー!
     ノヽノヽ
       くく
064563805/02/24 11:50:40ID:???
use Text::CSV_XS;
my $csv = new Text::CSV_XS({ binary => 1 });
open FH,"test.csv";
my @array;
while (<FH>){
jcode::convert(\$_,"euc");
$csv->parse($_);
push @array,$csv->fields;
}
close FH;

こういう$_これをjcodeに渡して変換してもらうのってありですか?
一応動くのですが、行儀悪い行為になるんでしょうか?
なんか<FH>を直接書き換えているみたいで怖いんですが;
0646nobodyさん05/02/24 11:55:08ID:???
>>645
とりあえずchompしとけ。
0647nobodyさん05/02/24 12:29:11ID:???
>>630
正直「エスケープ」というのがいまいちよくわからない。
open(PIPE," | sendmail $address") するときに $address の中に shell のメタ文字が
という対 shell サニタイズの話なのか?

俺がメールフォーム作るなら、そういう問題を考えなくて良いように Net::SMTP を使う。
もちろん、宛先アドレスが valid かどうかというのは検証するし、
Subject とかのマルチバイト文字は MIME エンコードするけど、
それって「エスケープ」の話じゃないよな。
0648nobodyさん05/02/24 12:33:23ID:???
...2005/02/23(水) 23:06 [Perl] タイトル
関東と北陸、近畿に春一番
...2005/02/22(火) 21:07 [Windows] 無題
あいうえお
かきくけこ
...2005/02/21(月) 23:15 [Perl] 勉強
ああああ
ええええ

上のようなテキストから、
指定した文字列が含まれる(行頭が...の)タイトル行と、
その本文(内容)を抽出して出力するスクリプトを作りました。
動作しているのですが、
このようなwhile (<>) {の中にさらにwhile (<>) のある使い方が
書籍などを見ても見つからず分からないのですが、誤った使い方ですか?
もし間違いなら、どのような処理にすれば良いのか教えて下さい。
064964805/02/24 12:33:59ID:LxzKNGW5
$sample = "Perl";
while(<>){
 if(/^\.\.\..*\[$sample\]/){ # もし行頭に...がある場合
   $title=$_;
   print "$title";    # タイトル行の出力

   while(<>){
     if(!/^\..*/){    # もし行頭に.が無い場合
       $body=$_;
       print "$body"; # 本文の出力
     }
     if(/^\..*/){    # もし行頭に.がある場合
       last;
     }
   }
 }
}
065063005/02/24 13:15:43ID:Q/hMlpe6
>>647
open MAIL,"| /usr/sbin/sendmail -t";
print MAIL 'To: '.$form{to}."\n";
print MAIL 'From: '.$form{from}."\n";
print MAIL 'Subject: '.$form{subject}."\n\n";
print MAIL $form{body};
close MAIL;

こういうときに@form{qw/to from body/}に含まれてる危険な文字をエスケープするって
意味ですが、そもそも始めはフォームメールにXSS対策的なエスケープが必要だとは
思っていませんでした。

メールのヘッダである@form{qw/from to/}の値には改行を許してはいけない程度でしか
考えていませんでした。

その後、人にフォームメールを作るならエスケープのために相当な知識が必要だといわれました。
なのでそうなんだぁと思って、今回まずはまともなフォームメールを教えてもらって、
それを見ながらどういう文字に気をつければいいかを勉強しようかなと。

ネット上でsendmail エスケープで見てもイマイチ関係のありそうなのが出てこないんですよね。
sendmail系で出てくるのはメールアドレスの正規表現やソレヨウノモジュール。
ついでにsubject用のエンコード方法あたりがほとんどですね。

>open(PIPE," | sendmail $address") するときに $address の中に shell のメタ文字が
>という対 shell サニタイズの話なのか?
そうだと思います。そんな感じで言われました。ただUNIX系の話ですか?と聞いてから
返事がないのでよくわかりません。
065163005/02/24 13:18:55ID:Q/hMlpe6
742 :nobodyさん :05/02/10 16:15:16 ID:???
CGIでエスケープすべき文字についてお尋ねします。
sendmailでメールを送るときに本文やToをユーザが入力した内容に
する場合はどういう文字をエスケープすればいいでしょうか?

743 :nobodyさん :05/02/10 16:59:49 ID:???
>>742 おぼえること大杉

744 :742:05/02/10 18:59:35 ID:???
>>743 Toにクエリを埋め込む時もメールのヘッダーが終わった後の本文でも 同じエスケープではないですよね?
とりあえず現状ではToの方は\だけエスケープしてます。 本文のほうは何もしてないままです。
UNIXのコマンド文になるようなのを気をつけなければならないのでしょうか?

745 :nobodyさん :05/02/10 22:07:44 ID:???
>>744
もしお前が釣りなら、俺を感動させたことを誇っていい。お前には才能がある。
もし本気でメール出すCGIを作るつもりなら、かなり道は険しいぞ。

746 :nobodyさん :05/02/10 23:14:42 ID:???
>>744
つ[ ttp://www.ipa.go.jp/security/awareness/vendor/programming/ ]
とりあえずここでもどうぞ これ読んだ上でsendmailに特化した話
0652nobodyさん05/02/24 13:19:33ID:???
>>649
タイトルに$sampleを含むデータが連続してると、偶数番目のデータが表示されない。
二重ループでもできるが、単ループでフラグ使った方が簡単かと。

my $target;
while (<>) {
 /^\.{3}/ and $target = /\Q[$sample]/;  # 行頭が...なら対象データか判断
 print if $target;  # 対象データなら出力
}
065364905/02/24 13:58:07ID:???
>>652
レスありがとうございます。
仰るとおり連続してると偶数番目が表示されませんね。
気が付きませんでした。
フラグを使うとここまで短くなるとは。。。

もっと勉強してきます。
ありがとうございました。
065463805/02/24 14:12:15ID:???
今はファイルの中身を読んで変数に入れるのをサブルーチンにしています。
しかし今後を考えて外部のライブラリファイルにまとめたいと思います。

そこで一つ問題点。
UNIX環境でCGIを動かすと、ライブラリ内でcsvファイルパスを相対パスで設定しても
カレントディレクトからの相対パスになってしまいますよね。

これでは色々なファイルから読めません。
環境が違えばこの前提も変わるかもしれません。
なので読み込む側から読み込むファイルへのパスを引数として持たせようかと考えました。

しかしよく考えると、それっておかしいですよね;
ライブラリがどのファイルを読むかを呼び出し側で設定しないといけないと、
なんかオブジェクト志向チックではないというか;
まあモジュールにしなければいいみたいな勢いですが。

ああ。よくわからん、もういいや。
0655nobodyさん05/02/24 15:34:07ID:???
>>654
モジュールの中でファイルを絶対パスで指定しておき、デフォルトではそれを使う
デフォルト以外のパスを使う場合は、呼び出し側からコンストラクタの引数で指定する
というのがよくあるやりかただと思う
0656nobodyさん05/02/24 17:33:07ID:???
qw/a 1 2/;
この0番目をキーとしてそれ以降をそれぞれ違うハッシュの値としたいです。

my %hash;
sub{
@hash{qw/hoge hage/}->{$_[0]} = @_[1,2];
}->(qw/a 1 2/);

こんな感じで%hashの中にhogeとhageを作り、hogeとhageはそれぞれハッシュのリファレンスで、
それに大して値を一発で渡したかったのですが、エラーでした。

$hash{hoge}->{$_[0]} = $_[1];
$hash{hage}->{$_[0]} = $_[2];

ブサイクですがこういう方法しかないのでしょうか?
0657nobodyさん05/02/24 17:44:00ID:???
よくわからんけどこーゆーんがやりたいの?

$hash{'hoge'}->{$_[0]} = [ @_[1 .. @#_], ];
065865605/02/24 17:52:16ID:???
>>657
$hash{hoge}->{$_[0]} = $_[1];
$hash{hage}->{$_[0]} = $_[2];

これを一行で済ませたいんです。本当はhogeは10種類くらいあるのです。
なのでいちいち10行も使うと汚くなるので・・・
0659nobodyさん05/02/24 18:11:55ID:???
>>658
my $k = shift;
foreach (qw(hoge hage)) {
$hash{$_}->{$k} = shift;
}

でいちおうできると思うが、なんとなくデータ構造
見直したほうがいいんじゃないかという気もする。
066065605/02/24 18:19:24ID:???
>>659
ブロックですか・・・・
0661nobodyさん05/02/24 18:43:18ID:???
ブロックがいやなら:

my $k = shift;
$hash{$_}->{$k} = shift foreach (qw(hoge hage));


0662nobodyさん05/02/24 18:47:04ID:???
656に近い形で書くなら、
sub{
$hash{$_}->{$_[0]} = splice(@_,1,1) for qw/hoge hage/
}->(qw/a 1 2/);

でも、
>いちいち10行も使うと汚くなるので・・・
何ヶ所かで使うんだったら、659を関数化して使った方がいいと思うぞ。
066365605/02/24 20:13:43ID:???
>>661-662
やはり
@hash{qw/hoge hage/}->{$_[0]} = @_[1,2];
こういうのは無理なんですね。

色々あげてもらって悪いのですが、ぱっと見の読みやすさで
$hash{hoge}->{$_[0]} = $_[1];
$hash{hage}->{$_[0]} = $_[2];
こうしておきます。

これをするのは外部サブルーチンにすることで良しとしておきます。
すみませんですm(_ _)m
0664nobodyさん05/02/24 22:09:00ID:???
print qq|
@{[
map {"$i : $_<br>"} @array
]}
|;

こういう出力中にやるmapの中で$iに何回目のループかを持たせるにはどうすればいい?
my $i;
まずこれができないんだよね。
さらにmap {"$i : $_<br>"; $i++} @array
とすると$i++の渡されちゃう。なんか方法ないかな?
0665未承諾広告※ ◆TWARamEjuA 05/02/24 22:29:23ID:???
map { sprintf "%d : %s<br>", $i++, $_ } @array;
とか。
0666nobodyさん05/02/24 22:50:07ID:???
>>665
myはどうする?
0667nobodyさん05/02/24 22:50:38ID:???
>>666
localにする。
0668nobodyさん05/02/24 22:59:23ID:???
print qq{
@{[
map( "$_ : $array[$_]<br>", 0..$#array )
]}
};
じゃ、ダメなん?
0669nobodyさん05/02/24 23:08:22ID:???
1、特定のホストからアクセスを禁止したい
2、無知なので何もできず。。。
3、頭のエラーがでてできなかったw
0670nobodyさん05/02/24 23:30:51ID:???
>>667
どういうちがいがあるの?
0671nobodyさん05/02/24 23:49:43ID:???
>669
まずは頭のエラーを治してきて。
それはどうしようもねーや。
0672nobodyさん05/02/25 00:04:58ID:???
ハッシュの中にリファレンスも含んでる時ってどうやって安全にメソッドに渡すの?
&routin({%hash});
こうすると%hash自体は安全に見えるけど、もしもこの中身が
my %hash = (a=>1 , b=>[qw/1 2 3 4 5 6/] , c=>\("あいうえお"));

こんなのだったらbとcは渡された先でいじられた時にメイン側の$hash{b}にも
影響出るよね。
0673nobodyさん05/02/25 00:11:41ID:???
>>668
keys 使ったハッシュの場合とかじゃない?
0674nobodyさん05/02/25 00:17:31ID:???
>>672
参照を持つ言語は皆同じことで悩むね。
0675nobodyさん05/02/25 00:22:39ID:???
うむ、どうしようもないな

リファレンスの中身を再帰的に嘗めてってツリー全体を複製する手もあるのかもしれんが
ファイルハンドラやソケットを持ってると原理的にお手上げだし
0676nobodyさん05/02/25 00:25:59ID:???
さわんな禿げ!がベター。
0677nobodyさん05/02/25 01:05:47ID:???
改行コードの置換をしたくて
$value =~ s/\r\n|\r/\n/g;
としたのですが、これでは間違いようで馬鹿にされました。
$value =~ s/\x0A\x0D|\x0A/\0D/g;
JISの改行コードというサイトをみたらこれで合ってると思うのですが、大丈夫ですか?

それと改行コードはどうして\nでマッチを期待してはいけないのでしょうか?

067867205/02/25 01:08:15ID:???
>>674-676
おぅ、みんなそこらへんは適当にごまかしてるわけね^^;
まぁしょうがないかな。壊されては困るものは面倒でも一旦完全に紐解くよ。
ソケット云々はまだ知らないのでそこらへんはまたいずれ悩むかなw
0679nobodyさん05/02/25 01:14:10ID:???
>>677
>>585
0680nobodyさん05/02/25 02:37:30ID:???
>>672
弄られたくないものは渡さない。
■ このスレッドは過去ログ倉庫に格納されています