Perlコーディング初心者質問スレ Part 54
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
2007/02/10(土) 19:21:23ID:???【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。
1: 自分はこういう事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。
お勧めサイトは >>2-10
前スレ http://pc10.2ch.net/test/read.cgi/php/1164519503/
過去ログ倉庫 ttp://user.ftth100.com/mirrorhenkan/perl/
0554nobodyさん
2007/04/05(木) 00:54:13ID:???0556nobodyさん
2007/04/05(木) 11:31:17ID:???配送エラーのとき、$from_mailに返信させたいのですができません。
$from_mail="[email protected]"; # $from_mailは存在します。
$to_mail="[email protected]"; # $to_mailは存在しません。(hoge2.jpは存在しないものとします。)
open (MAIL,"| $mail_pass -t") || &error("posfixエラー");
# print MAIL "Error-To: $from_mail\n"; # Error-To:ヘッダがあっても無くても返ってきません
print MAIL "From: $from_mail\n";
print MAIL "To: $to_mail \n";
これを実行したところ、エラーの連絡が$from_mailに送信されません。
上記と同じメールの内容で、outlookを使用して、手作業で送信すると
件名:failure notice のエラーのメールが、返ってきました。
・posfixの設定で、足りないものあるのでしょうか?
・perlのプログラミングで、足らないことがあるのでしょうか?
よろしくお願いします。
0557nobodyさん
2007/04/05(木) 11:42:22ID:???> $from_mail="[email protected]"; # $from_mailは存在します。
> $to_mail="[email protected]"; # $to_mailは存在しません。(hoge2.jpは存在しないものとします。)
メール送信以前の問題なので$from_mail,$to_mailの値をチェックすることを
お勧めします。
ヒント: 文字列リテラルへの(配列)変数の埋め込み
0558nobodyさん
2007/04/05(木) 11:43:28ID:???シングルクォートで
$from_mail = '[email protected]';
$to_mail = '[email protected]';
としてやればおk
# hoge.jpは実在するドメインだから、こういうときの例にはexample.comを使おうな
0559nobodyさん
2007/04/05(木) 12:29:53ID:???>>558
お返事ありがとうございます。
シングルクォートに変更し、存在するメールには、
送信できること確認できました。
[cgi]
$from_mail = '[email protected]';
にしてみましたが、配信エラーの通知がされませんでした。
また、ドメイン検索で存在しないことを確認したドメインを
指定してもだめでした。
[outlook]
手作業で送信したとき、配信エラーが返って来るか確認してみました。
存在しないことを確認したドメインで、outlookでyahooや他のメールサーバから
送信すると戻ってきましたが、'[email protected]'は、戻ってきませんでした。
[考察]
ドメイン検索で存在しないことを確認したドメインで
outlookから送信すると、普通にエラーが帰ってきました。
cgiだと帰ってきません。cgiでなにかおかしいんじゃないかと思ってます。
open (MAIL,"| $mail_pass -t")の-tオプションが無いと
メール送信できなかったので付けてます。
思い当たることなどありますでしょうか。
よろしくお願いします。
0560nobodyさん
2007/04/05(木) 13:09:03ID:???まったく無関係で、送信プログラムにsendmail(postfixのsendmail互換コマンド)
を使っているならばプログラムを実行したユーザのアドレスになるのがデフォルトで、
変更したい場合は-fオプションで指定する必要がある。
open (MAIL,"| $mail_pass -t -f $from_mail")
0561nobodyさん
2007/04/05(木) 16:00:15ID:???丁寧な解説ありがとうございます。
open (MAIL,"| $mail_pass -t -f $from_mail")
にしてみましたが、配送エラーのメール送信されませんでした。
Envelope-From:ヘッダー、を試しましたがエラーは返信されませんでした。
cgiじゃなくて、postfixの設定ファイル/etc/postfix/main.cf
の設定がおかしい可能性高いでしょうか?
/etc/aliasesの設定がおかしいのかと思いまして、
FROM:ヘッダーを除いて、存在するメールを指定すると、
送信者はApache表示で$from_mailは、きちんと指定されていました。
$from_mailは、レンタルサーバのメールアドレスですが、
postfixサーバから普通に送信できるので、大丈夫だと思うのですが。
ん〜。難しいです。
0562nobodyさん
2007/04/05(木) 16:40:06ID:???postfixのログを見られるなら見るのが一番だが、レン鯖などで
見られないなら、まず自分に送ってみて届いたメールが思い通りに
なっているか確認するのが基本だな。
envelope fromはたいていreturn-pathというヘッダに保存されるので
それが自分が設定したつもりのものか確認するといい。
0563nobodyさん
2007/04/05(木) 16:56:54ID:???自宅サーバで、勉強してます。
違うcgiの過去の受信メール見てみるとReturn-Path:があるときと、
無いときがありました。ということは、cgiがおかしいのかもです。
どうもありがとうございました。
原因がわかりましたら、報告いたします。
0564nobodyさん
2007/04/05(木) 18:06:22ID:2CVq1dn3で、ググった結果jcodeg.plを知り、これをアップロードして、半角文字のみで
書き込みのテストをしたらちゃんと半角で表示されました。
とここまでは良かったのですが、文章に全角と半角文字を混ぜた状態で
投稿すると、投稿後の記事内の文章が全て全角で表示されてしまいます。
入力した通りに投稿するには、jcodeg.plのドコを変更したらよいのでしょうか?
0565nobodyさん
2007/04/05(木) 18:58:00ID:???0566nobodyさん
2007/04/05(木) 18:59:13ID:???0568nobodyさん
2007/04/06(金) 07:42:58ID:???port25は開けていました。
試しにコマンドラインで、[email protected]に送信してみました。
--------------------------
# /usr/sbin/sendmail -t
Envelope-From:"普段のメール"
To:[email protected]
.
--------------------------
で送信しましたが、配送エラーのメール返って来ませんでした。
・コマンドのオプション
・Envelope-From:"普段のメール"で、何かあるのか。
いろんなメール指定してみましたがダメでした。
・ヘッダーオプションで他に何か必要か
ぐらいと思うのですが、どのあたりがおかしいでしょうか。
これが解決したら、perlにそのまま反映すれば
配送エラー返ってくる気がするんですが。。。
よろしくお願いします。
0569nobodyさん
2007/04/06(金) 09:53:13ID:???Envelope-From: などというヘッダはない。
# /usr/sbin/sendmail -t [email protected]
To: [email protected]
本文…
.
#
のように指定します。-fの直後に指定するのがenvelopeアドレスです。
上記の場合、envelopeアドレスに何かメールを戻したいなら、Toヘッダのアドレスを
実際に存在しないアドレスとか、ドメインにしてみないと、Toのアドレスに普通にメールが
届いて終わるので注意。
さもなくば、telnet localhost 25 でMTAと直接交信してみるとか。
0570nobodyさん
2007/04/06(金) 12:41:32ID:???お返事ありがとうございます。
#/usr/sbin/sendmail -t -f<存在するメール>
To:[email protected]
エラーメール戻ってきませんでした。
メールが送信できたのか、送信できていないのかも区別が付きません。orz
DNSの設定かと思い検索してます。
スレ違いになってきてしまいまい、申し訳ないです。
maillogは、下記の通りです。
Apr 6 12:26:04 localhost postfix/pickup[20462]: 4CCACC04193: uid=48 from=<存在するメール>
Apr 6 12:26:04 localhost postfix/cleanup[20527]: 4CCACC04193: message-id=<・・・@mail.example.com>
Apr 6 12:26:04 localhost postfix/qmgr[17310]: 4CCACC04193: from=<存在するメール>, size=301, nrcpt=1 (queue active)
Apr 6 12:26:04 localhost postfix/qmgr[17310]: 4CCACC04193: to=<[email protected]>, relay=none, delay=0,
status=deferred (delivery temporarily suspended: Host or domain name not found. Name service error for name=example.jp type=MX:
Host not found, try again)
0571570
2007/04/06(金) 19:26:09ID:???経過ですが、存在しないメールアドレスに送信した場合、
delivery temporarily suspended: Host or domain name not found.
Name service error for name=example.jp type=MX: Host not found, try again)
このパターンになるようです。
やっぱり、エラーのメールが自分に帰ってこないと不便ですよね。
tailf maillogで、眺めていたら突然、上記のパターンでログが大量に流れました。
昔送信したでたらめなメールで、しかも、try againっていうぐらいなので、
送信されずに、再送待ちになってるみたいです。
ttp://www.postfix-jp.info/trans-2.0/jhtml/faq.html
あとは、再送待ちじゃなくて、配送エラーが送信すればいいんですね。
再送のメールはどこにあるのとか、いろいろ、つまずいてます。
あとちょっとのような気がしてきました。
丁寧にレスありがとうございました。
0572570
2007/04/07(土) 04:16:46ID:???で解決しました。
ログを見ることと、検索能力が少しアップしました。
ありがとうございました。
0573nobodyさん
2007/04/07(土) 18:44:41ID:MSfJ44Rvよいですか?
Linuxです。
0574nobodyさん
2007/04/07(土) 18:50:58ID:???とか置いてそこからlwpなりで適当に
取ってくればいいんじゃないすか
0575573
2007/04/07(土) 19:10:45ID:MSfJ44RvPerlでグローバルIPを取得する関数がないとすると、
シェルで組んだ方がよさそうですね。。
ありがとうございました
0576nobodyさん
2007/04/07(土) 19:31:41ID:???とか勝手なこと言ってみる
0577nobodyさん
2007/04/07(土) 19:56:03ID:???127.0.0.1みたいなのを取り除いて残ったもの」とすればよさそうだが、
これを複数もつホストもあるだろうなぁ。
0578nobodyさん
2007/04/08(日) 03:05:36ID:???ルータやファイアウォールがあってNATされているのかで話が違ってくる。
後者の環境の方が多いんじゃないか。
だとすると、外部のサーバにアクセスしてそのサーバ側から教えてもらうとか。
あるいは、ルータの管理画面を自力で取得してパースするとかね。
0579nobodyさん
2007/04/08(日) 04:54:35ID:???場合によってはこんな方法も
use Socket;
print inet_ntoa(scalar gethostbyname($ENV{HTTP_HOST}));
0580nobodyさん
2007/04/08(日) 06:44:51ID:???俺はDDNSの更新する時ルータに教えてもらってる
0581nobodyさん
2007/04/08(日) 09:30:52ID:???http://pc11.2ch.net/test/read.cgi/tech/1112553783/
本人か?
0582nobodyさん
2007/04/08(日) 09:31:57ID:???0583nobodyさん
2007/04/08(日) 10:08:34ID:???そこから「10」という数字の列だけを参照するには
どうすればいいのでしょうか?
index関数だと100や210など10が含まれていたら
抜き出してしまうので悩んでいます。
検索で調べる場合の検索用語でもかまいませんので、アドバイスお願いしますorz
0584nobodyさん
2007/04/08(日) 10:54:12ID:???詳しく日本語で
0585エスパー
2007/04/08(日) 11:35:44ID:???をエスパー日本語訳してみる。
こんな内容のファイルがあります。
--------
210 hoge
10 foo
100 guge
10 zoo
123 boo
--------
この場合 "10 foo" と "10 zoo" の行だけを抜き出したいのですが、index関数だと
210、100 といった行も含まれてしまいます。
どしたらいいの? お前らとっとと教えろ。
0586583
2007/04/08(日) 12:42:51ID:???$xx =~ /^$yy$/ でいけました。お手数かけました、ごめんなさい。
0587nobodyさん
2007/04/08(日) 12:58:04ID:???だがな、それなら eq で比較するだけでもよさそうだな。
0588nobodyさん
2007/04/10(火) 04:15:40ID:???> 過去ログ倉庫 ttp://user.ftth100.com/mirrorhenkan/perl/
これ見ようとするとリダイレクトされて過去ログ閲覧不可なのね。
> 現在、mirrorhenkan/perl/ はFREESPACE利用規約の禁止事項に
> 抵触しているためアクセスを制限しております。
0589nobodyさん
2007/04/11(水) 01:18:30ID:???open(IN, $file);
@list = <IN>;
------------------------------------
#�Awhileで一行ずつ読み込んで処理
open(IN, $dfile);
while ( $line = <IN >) {
#$lineを区切り文字を分割して、何か処理
}
何十Mというサイズの大きいCSVファイルを扱うときが前提です。
�@だと配列に格納するみたいですが、メモリの消費は大変でしょうか?
�Aのほうがよいでしょうか?
0590nobodyさん
2007/04/11(水) 01:35:16ID:???(1)の方はCSVが1GBならメモリも1GB以上使うわけだが、(2)は
CSVのサイズが1MBでも10GBでも変わらない。
ってことはわかってるわけだな。
答えわかってんじゃん。
しかし、割り切って(1)の方法を使う場合もあるよ。
書き捨て的なスクリプトとかだと。
っちゅうか、丸数字やめね?
0591nobodyさん
2007/04/11(水) 03:38:11ID:???パソコンの仕組みとperlの勉強を、はじめたばかりで、
メモリの動きとか、あまり考えたこと無かったので、
ちょっと自信がありませんでした。^^;
どうもありがとうございました。
0592nobodyさん
2007/04/11(水) 04:20:00ID:???そんなコンパクトに収まるかよw
0593nobodyさん
2007/04/11(水) 10:31:55ID:???少しお尋ねします。
例えば
perl -pi.bak -e "tr/A-Z/a-z/"*.html
とか便利ですよね?
これを.plとして使いたいのですが無理なのでしょうか?
コマンドラインから打ち込むしか手がないのでしょうか?
0594nobodyさん
2007/04/11(水) 10:41:24ID:???http://pc11.2ch.net/test/read.cgi/tech/1173880452/235
0595nobodyさん
2007/04/11(水) 10:41:25ID:???0596nobodyさん
2007/04/11(水) 10:45:21ID:???こちらに変えました。
申し訳ない。
0597nobodyさん
2007/04/13(金) 14:21:28ID:ZxZihQHU0598nobodyさん
2007/04/13(金) 14:45:10ID:???詳しくはperlvar(1)の
Technical Note on the Syntax of Variable Names
を読め。
0600nobodyさん
2007/04/13(金) 17:45:43ID:???$::HOGE = 1;とかもだめ?
後はこんなの書いといてプログラムの頭でuseするとか
package Global;
use strict;
use warnings;
use base qw(Exporter);
our @EXPORT = qw($BAKA $AHO $SHINE);
our $BAKA = 1;
our $AHO = 'a';
our $SHINE = 'A';
push(@UNIVARSAL::ISA,__PACKAGE__);
package TEST1;
use strict;
use warnings;
printf "%s::BAKA=%s\n",__PACKAGE__,$BAKA++;
printf "%s::AHO=%s\n",__PACKAGE__,$AHO++;
printf "%s::SHINE=%s\n",__PACKAGE__,$SHINE++;
package TEST2;
use strict;
use warnings;
printf "%s::BAKA=%s\n",__PACKAGE__,$BAKA++;
printf "%s::AHO=%s\n",__PACKAGE__,$AHO++;
printf "%s::SHINE=%s\n",__PACKAGE__,$SHINE++;
0601nobodyさん
2007/04/13(金) 18:12:42ID:???importするのが普通の方法なので、あまり変なことをせず従っておいたほうが
なにかといいと思われ。
0602597
2007/04/13(金) 20:19:19ID:ZxZihQHUありがとうございます。試してみます。
何に使うってわけじゃなくて、そういうことが出来るのなら知りたいなと思いまして。有難う御座いました。
>>599
顔が見えないからってそういう言い方はしないほうがいいでしょうね。
0603nobodyさん
2007/04/14(土) 04:03:04ID:???検索機能をつけて、検索語句を$wordとし、
$dataに一致するものがあれば、って形でやってます。
if($data =~ /\Q$word\E/){
すると、「[」で「ー」もヒットしてしまったりします。
これは「ー」に「[」のコードが含まれているからだと思うのですが、それを除外する方法はどうしたらよいでしょうか?
0604nobodyさん
2007/04/14(土) 04:08:26ID:???0605nobodyさん
2007/04/14(土) 04:17:21ID:???なるほどutf8という方式だとコードの重複がないんですね
検索語句と、検索対象をutf8に一旦エンコしてから、ってやり方にしてみます。
有難う御座いました。
0606nobodyさん
2007/04/14(土) 05:37:58ID:???みたいな感じに簡単にできると思ってましたが、複雑ですね。
一時的に対象の$変数をutfに変換して戻す簡単な方法は御座いませんでしょうか?
調べた限り、utfでスクリプトを書くことが前提の記事ばかり出てきてしまいます。
0607nobodyさん
2007/04/14(土) 10:35:22ID:???0608nobodyさん
2007/04/14(土) 11:07:17ID:???my %hash = ();
$hash{a}{b}{c}{d} = 'test';
↑の場合だと自動的に {b}{c}{d}の部分が無いのに自動的に作られてしまいます。こういうのを防ぎたいのですが・・
0609nobodyさん
2007/04/14(土) 11:22:25ID:???既にありそうだけど。
0610nobodyさん
2007/04/14(土) 12:46:48ID:???http://pc11.2ch.net/test/read.cgi/tech/1173880452/10
0611nobodyさん
2007/04/14(土) 12:50:45ID:???http://pc11.2ch.net/test/read.cgi/tech/1173880452/10
utf8でスクリプト書くことがそんなに困るの?
今あるsjisやeucのスクリプトをエディタなどで変換するだけでしょ。
0612nobodyさん
2007/04/15(日) 03:41:41ID:???困るというか、モバイル機などでutf8がバケる機種があってそれに対する対策が自分はまだわかってないってだけです。
気分を害してしまったのならすみません。
0613nobodyさん
2007/04/15(日) 03:57:25ID:???0614nobodyさん
2007/04/15(日) 09:33:34ID:???古い機種つかってる人なんか無視
0615nobodyさん
2007/04/15(日) 11:29:23ID:???古い機種の携帯からのアクセス時だけJcode.pmか何かで
Shift_JISにエンコードすればいいだけの話じゃね?
if($ENV{HTTP_USER_AGENT} =~ /<適当に古い携帯の条件>/){
require Jcode;
$data = Jcode->new($data, 'utf8')->sjis;
print "Content-Type: text/html; charset=shift_jis\n\n";
print $data;
}else{
print "Content-Type: text/html; charset=utf-8\n\n";
print $data;
}
みたいに
0616nobodyさん
2007/04/15(日) 14:24:51ID:???611のリンク先をよく読んで。
utf-8を使うのは、あくまでもPerlスクリプトだけであって、
入出力はsjisだよ。
0618nobodyさん
2007/04/16(月) 08:23:29ID:???「Perlスクリプトはsjisで、内部で扱うデータは
utf8というのはできない」という事で、FAなのかな?
0619nobodyさん
2007/04/16(月) 11:00:24ID:???Windows上であっても。
0620nobodyさん
2007/04/16(月) 13:15:51ID:MjOOmdj6どのような方法がよいでしょうか?
指定方法は、
1.X行目からY行分
2.最終行(何行目かは分からない)から数えてX行目からY行分
の2通りです。
0621nobodyさん
2007/04/16(月) 14:24:24ID:???Perlで扱うマルチバイト文字は、内部的には「常に」utf8だよ。
use encoding を使えばsjis でスクリプトを書くこともできるが、
副作用があるから、よく理解した上で使わないといけない。
>>620
File::Tieを使うのが吉
0624nobodyさん
2007/04/16(月) 18:55:47ID:???}
このような条件式をもっとスマーティーに書きたいのですが・・・
良きアイデアをお願いします!
0625nobodyさん
2007/04/16(月) 19:12:41ID:???&foo;
}
0626nobodyさん
2007/04/16(月) 19:18:36ID:???なんか自分が情けなくなってきました・・
0630nobodyさん
2007/04/16(月) 22:29:15ID:???0631nobodyさん
2007/04/16(月) 22:35:41ID:???$x > -1 && $x < 1
は、個人的には直感的じゃないと思った。
こう書くんだとしても
-1 < $x && $x < 1
にしたほうが視覚的に分かりやすい。
0632nobodyさん
2007/04/16(月) 23:05:14ID:???とか書けたら一番幸せなんだけどな。
# ソースフィルタ使えばできるか?
0633nobodyさん
2007/04/16(月) 23:17:54ID:???0634nobodyさん
2007/04/16(月) 23:28:48ID:???0635nobodyさん
2007/04/16(月) 23:51:39ID:???他のサービスも同時に動いていて、Perlが使用してるメモリだけを知りたい。
0636nobodyさん
2007/04/17(火) 03:37:59ID:???0637nobodyさん
2007/04/17(火) 06:11:09ID:nSKTWe9a男性 $mensfile
女性 $ladysfile とメインのCGIで設定されていす。
チャレンジしてみたら、過去のログファイルが全て消えてしまい散々な目に会いました。下のどちらかでできそうな・・宜しくお願い致します。
(1)# 二重登録のチェックをします
if(-e $data){
open(FILE, "< $data"); # この時点でファイルは必ず存在します
while(<FILE>){
@v = split(/\t/);
if(@v[0] eq $name){
print "<center><b>すでに$nameさんは登録されています</b><br>\n";
print "「戻る」を押して入力しなおしてください</center>\n";
exit(0);
}
}
close(FILE);
}
0638637
2007/04/17(火) 06:12:56ID:nSKTWe9a&lock;
if(!open(IN,"$mail01"))
{print 'ファイルOPENができませんでした。',"\n"; exit;}
@dataline = <IN>;
close(IN);
unlink $lockfile;
foreach $DATA (@dataline) {
chomp $DATA;
if($DATA eq $MAIL){
print 'このメールアドレスは既に登録されています。',"\n";
exit;
}
宜しくお願い致します。
0639nobodyさん
2007/04/17(火) 09:23:10ID:???二重登録チェックの方法はひとまず置いといて、
ログファイルが消えちゃったってことは
書き込みの段階でしくじってるんじゃないの?
ありがちな例だと
× open (FILE, '> file.txt'); # 上書き(つまり消える)
○ open (FILE, '>> file.txt'); # 追加書き込み
とか。
0640nobodyさん
2007/04/17(火) 09:43:54ID:???ないし、ここで回答もらえるレベルに達してない質問の典型だね。
「日本語でOK」「エスパー回答者さんよろしく」ということで。
質問する側にも最低のスキルは必要で、問題を理解してもらえないことには
どうにもならんよ。
0642nobodyさん
2007/04/17(火) 10:35:21ID:???0644nobodyさん
2007/04/17(火) 17:05:48ID:???! int $x and ! int $y
って手もある罠、、、
0646nobodyさん
2007/04/17(火) 17:13:38ID:???0648nobodyさん
2007/04/17(火) 23:26:16ID:???何となくスレの雰囲気から察すると
『はじめてのPerl』マスターレベルは初心者じゃないよね、もう。
『続・はじめてのPerl』に至っては
題名だけ聞くと優しそうだけど、
マスターしたら、CPAN Authorくらいなれちゃうし。
俺的には、『はじめてのPerl』読みこなし中レベルだと解釈してるが、どうか?
0649nobodyさん
2007/04/18(水) 00:03:35ID:???じゃないかな
0650nobodyさん
2007/04/18(水) 00:12:31ID:???0651nobodyさん
2007/04/18(水) 08:05:12ID:???0652nobodyさん
2007/04/18(水) 10:28:13ID:???ファイルから読み込むことは可能でしょうか?
pack('C4', 255, 255, 255, 255) とすると4バイト(FF FF FF FF)になるかと思ったんですが、
8バイト(C3 BF C3 BF C3 BF C3 BF)になってしまいます・・・
0653652
2007/04/18(水) 11:33:42ID:???■ このスレッドは過去ログ倉庫に格納されています