|
> 2000/10/01の三日まえを表示したいのですが Time::Local で time_t 形式に変換し、3日分の秒数を引いてから、 再度 localtime で年月日の形式に戻します。 use Time::Local; $time = timelocal(0,0,12,1,10-1,2000-1900); $time -= 60*60*24*3; ($sec,$min,$hour,$day,$mon,$year) = localtime($time); printf "%4d/%02d/%02d",$year+1900,$mon+1; > メールが大量に届いたり メールが何通届いていて、それぞれサイズはどれだけか、という ことは、メール本文を取得する前に調べることができます。 また、これはメールサーバにもよりますが、あるメールの先頭 何行のみを取得、ということもできます。そういう機能を持つ メーラーを探してみてはどうでしょうか。 % telnet メールサーバ名 110 USER your_user_name PASS your_password LIST (メール一覧とサイズ表示) TOP 1 3 (1通目のヘッダと本文3行のみを表示) QUIT (終了) > 本文が最悪なタグの羅列だった場合 Windows はよく知らないんですが、HTML メールが送られて きたら、HTML として開くか plain text として開くかを 確認してきませんか? 聞いてこないなら、まともなメーラーに かえましょう。 |
|
68userさん > こないだは説明が足りずに済みません。助かりました。 またしても質問なんですが、 sh スクリプトで2つのファイルの内容が完全に一致した場合に aというファイルに 日付,"一致"(文字列)を出力して、 一致しなかった場合には 日付,"不一致"(文字列)を出力したいんですが 全然わかりません。よろしかったら教えてください。 |
|
ファイルの比較には cmp か diff を使います。一致 したかどうかはコマンドの戻り値を見ればよいですが、 sh なら $? で参照できます。あとはマニュアルを よく読んでみてください。 |
|
No.1269で、超初心者さんがやってたのと同じように、CGIからexpectスクリプト を呼び出して、他のマシンにtelnetしてパスワードを変更するシステムを作って いるんですが、telnetで戻ってきた文字が一部うまくexpectに渡されないようで 途中で止まってしまい、上手くいきません。 そこで$|=1にして出力を見たら、以下のところで止まっている事が分かりました。 spawn telnet server Trying xxx.xxx.xxx.xxx ... Connected to server.xxx.xxx. Escape character is '^]'. ”Escape character is '^]'.”の後に、CRLFが来るんですが、それから先が上手 くexpectに渡されていない(?)ようです。 HTTPdがCRLFだから止めてしまっているんでしょうか? それってHTTPdの仕様なんでしょうか? exec 'expect';の後のprint文はexpectのtimeout後に出力されます。 どこで止めてしまってしまっているかを調べる方法や解決方法など、アイディア がありましたら教えてください。 |
|
僕は expect 使ったことありませんのでわかりませんが、せっかく perl を使っているんですから、Net::Telnet モジュールでやって みてはいかがでしょう。 use Net::Telnet; $t = Net::Telnet->(Timeout=>10, Prompt => '/\w+?@\w+?: /'); $t->open('hostname'); $t->login('yourname', 'password'); @lines = $t->cmd("/bin/ls -l"); print @lines; $t->close(); 言うまでもないかもしれませんが、Prompt のところは適切に 変更しないと動きません。詳しくは perldoc Net::Telnet をどうぞ。 |
|
うーん、むずかしい…。全然理解してないことがよくわかった。 すごく汚くて変な書き方ですがこんな感じ。 use Net::Telnet; $username='yourname'; $oldpasswd='secret1'; $newpasswd='secret2'; $t = new Net::Telnet (Timeout => 5, Prompt => '/\w*? /', Dump_Log => 'telnet-log'); $t->open("localhost"); $t->login($username, $oldpasswd); $t->prompt('/Old password:/'); $t->cmd("/usr/bin/passwd"); $t->print("$oldpasswd\n"); ($prematch,$match) = $t->waitfor('/[a-zA-Z ]+:/'); print "[$prematch] [$match]\n"; $t->print("$newpasswd\n"); ($prematch,$match) = $t->waitfor('/[a-zA-Z ]+:/'); print "[$prematch] [$match]\n"; $t->print("$newpasswd\n"); ($prematch,$match) = $t->waitfor('/[a-zA-Z ]+:/'); print "[$prematch] [$match]\n"; $t->close(); 適当に $match の結果に応じて、パスワードが違うやら、 新しいパスワードが短いやら出力すればいいのかな。 expect の方がすっきり書けるような気も。 |
|
やっぱ僕がやるとしたら pw コマンドの wrapper 作って、 それを root に suid するなぁ。passwd の挙動を 全て把握するのは厳しい。 |
|
結局、68userさんのおっしゃる通りpasswdの挙動を全て把握するのは 厳しいので、telnetされる側のServerにID,Passwordを変数として受け 取って、passwdファイルを直接編集するperlを置き、それをCGI(Perl) からtelnetして、rootで実行させるようにしました。 結局何故expectで動作しないのかは不明なままですが、要求を満たす 物は出来ました。 アドバイスありがとうございました。 |
|
私の場合、次のような感じのスクリプトで動きます。 一応、ログインしてコマンド実行程度なら、大丈夫のようです。 環境は perl 5.00503 + Expect-1.08 + FreeBSD 4.2-BETA です。 #!/usr/bin/perl use Expect; my $user = 'rose'; my $password = 'password'; my $prompt = 'host\{rose\}\d+\s'; my @cmdlist = ( 'ls -alF', 'ps -auxw', 'exit', ); my $telnet = Expect->spawn("telnet localhost"); $telnet->expect(30,"login: ") || die "NO login prompt"; print $telnet "$user\r"; $telnet->expect(30,"assword:") || die "NO password prompt"; print $telnet "$password\r"; my $match = $telnet->expect( 30, "closed by foreign host", "-re", $prompt ); die "refused by server\n" if $match == 1; die "NO shell prompt, ".$telnet->exp_error()."\n" unless $match; foreach $cmd ( @cmdlist ) { print $telnet "$cmd\r"; my $match = $telnet->expect( 30, "closed by foreign host", "-re", $prompt ); last if $match == 1; die "NO prompt after command\n" if $telnet->exp_error(); } $telnet->hard_close(); exit; |
|
最近Unixを始めたのですが、サブルーチンの作り方がわかりません。 (呼び方、書き方) 簡単な例を教えていただけると幸いです。 |
|
awk scriptを使って下の様なことがしたいのですが、方法を教えて下さい。 Input File1: 10 abcde 9 bcdef 12 cdefg Input File2; 3 abcde 5 cdefg 12 defgh ファイル1と2を比較し、$2の内容が同じ場合、file1 と file2 の $1 $2 を output file の $1 $2 $3 $4に出力する。 比較して見つからない 場合はスペースを出力する。 Output file 10 abcde 3 abcde 12 cdefg 5 cdefg 3 abcde 12 defgh よろしくお願いします。 |
|
> サブルーチンの作り方がわかりません。 言語がわからないと何とも言えません。 > awk scriptを使って下の様なことがしたいのですが #!/usr/bin/awk -f BEGIN{ while (getline< ARGV[2] >0 ){ hash[$2]=$1 } while (getline< ARGV[1] >0 ){ if ( hash[$2] ){ print $1,$2,hash[$2],$2 } else { printf "%s %s \n",$1,$2 } delete hash[$2] } close(ARGV[2]); while (getline< ARGV[2] >0 ){ if ( hash[$2] ){ print $1,$2 } } } FreeBSD の awk と Solaris の nawk では動きましたが、 Solaris の awk では動かず。 うーん、awk らしくない…(笑) まぁ awk スクリプトを 書いたのは4年ぶりくらいなので、これで勘弁して下さい。 # 見本求む。 |
|
すみません。 Perlです。 |
|
> # 見本求む。 見本かどうか分かりませんが、私は次のように書きました。 #!/usr/bin/awk -f { array[$2] = sprintf("%s %s", array[$2], $1); } END { for( key in array ){ split(array[key], tmp); if( 2 in tmp ) printf("%s %s %s %s\n", key, tmp[1], key, tmp[2]); else printf("%s %s\n", key, tmp[1]); } } 起動は % awk -f script file1 file2 としてください。連想配列に記録して、最後に出力という感じです。 ただし、次のような $2 が同じだが $1 が違う値を含む形式のデータは 仮定していません。 10 abcde 11 abcde どちらかを捨てるようになっているかと思います。実際にはデータの形式の チェックが要るかと思います。あと出力の順が不定になります。出力の 順番に依存する処理には向きません。動作チェックはしていません。 多分、本家の awk じゃ無理かな。動作チェックは gawk でやっています。 |
|
># 見本求む。 単なるバリエーションということで… #!/usr/bin/awk -f NR == 1 { f = FILENAME } f == FILENAME { hash[$2]=$1 } f != FILENAME { if ( $2 in hash ) { print hash[$2], $2, $1, $2 delete hash[$2] } else print $1, $2 } END { for (r in hash) print hash[r], r } |
|
もう他人の書いた awk スクリプトを見ても意味がわからん (笑) > Perlです。 で、どういう処理をするサブルーチンの例を見たいのですか? あと、素人とか初心者とかいうハンドルはやめてください。 それから、誰に向けて言うわけでもないですが、回答をもらっても 返事をする気がないなら、最初から質問しないでね。 |
|
沢山の回答、どうもありがとうございます。 あとお礼が遅くなってどうもすいません。 試してみてから出そうと思っていたのですが、家にUNixがないので 月曜になってしまいます。 このページを発見して間もないのですが、これから色々質問することもある思うので、その時はまたよろしくお願いします! |