68user's page 掲示板

Prev< No. 1332〜1348> Next  [最新発言に戻る] [過去ログ一覧]
No. 1332 # 68user 2000/11/08 (水) 13:28:05
> 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 として開くかを
確認してきませんか? 聞いてこないなら、まともなメーラーに
かえましょう。

No. 1333 # M.K 2000/11/08 (水) 14:13:23
68userさん > こないだは説明が足りずに済みません。助かりました。
またしても質問なんですが、
sh スクリプトで2つのファイルの内容が完全に一致した場合に
aというファイルに 日付,"一致"(文字列)を出力して、
一致しなかった場合には 日付,"不一致"(文字列)を出力したいんですが
全然わかりません。よろしかったら教えてください。

No. 1334 # 68user 2000/11/08 (水) 15:21:31
ファイルの比較には cmp か diff を使います。一致
したかどうかはコマンドの戻り値を見ればよいですが、
sh なら $? で参照できます。あとはマニュアルを
よく読んでみてください。

No. 1335 # as 2000/11/08 (水) 16:35:03
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後に出力されます。

どこで止めてしまってしまっているかを調べる方法や解決方法など、アイディア
がありましたら教えてください。

No. 1336 # 68user 2000/11/08 (水) 22:25:40
僕は 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 をどうぞ。

No. 1337 # 68user 2000/11/08 (水) 23:17:49
うーん、むずかしい…。全然理解してないことがよくわかった。
すごく汚くて変な書き方ですがこんな感じ。

    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 の方がすっきり書けるような気も。

No. 1338 # 68user 2000/11/08 (水) 23:42:20
やっぱ僕がやるとしたら pw コマンドの wrapper 作って、
それを root に suid するなぁ。passwd の挙動を
全て把握するのは厳しい。

No. 1339 # as 2000/11/09 (木) 16:08:59
結局、68userさんのおっしゃる通りpasswdの挙動を全て把握するのは
厳しいので、telnetされる側のServerにID,Passwordを変数として受け
取って、passwdファイルを直接編集するperlを置き、それをCGI(Perl)
からtelnetして、rootで実行させるようにしました。

結局何故expectで動作しないのかは不明なままですが、要求を満たす
物は出来ました。

アドバイスありがとうございました。

No. 1340 # rosegarden 2000/11/10 (金) 02:48:35
私の場合、次のような感じのスクリプトで動きます。
一応、ログインしてコマンド実行程度なら、大丈夫のようです。
環境は 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;

No. 1341 # 素人 2000/11/10 (金) 11:29:00
最近Unixを始めたのですが、サブルーチンの作り方がわかりません。
(呼び方、書き方)
簡単な例を教えていただけると幸いです。

No. 1342 # ミング [E-mail] 2000/11/10 (金) 14:03:27
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

よろしくお願いします。

No. 1343 # 68user 2000/11/10 (金) 16:48:24
> サブルーチンの作り方がわかりません。
言語がわからないと何とも言えません。

> 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年ぶりくらいなので、これで勘弁して下さい。
# 見本求む。

No. 1344 # 素人 2000/11/10 (金) 17:17:12
すみません。
Perlです。

No. 1345 # rosegarden 2000/11/10 (金) 18:26:57
> # 見本求む。

見本かどうか分かりませんが、私は次のように書きました。

#!/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 でやっています。

No. 1346 # mm 2000/11/11 (土) 02:57:30
># 見本求む。

単なるバリエーションということで…

    #!/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
    }

No. 1347 # 68user 2000/11/11 (土) 15:18:07
もう他人の書いた awk スクリプトを見ても意味がわからん (笑)

> Perlです。
で、どういう処理をするサブルーチンの例を見たいのですか?
あと、素人とか初心者とかいうハンドルはやめてください。

それから、誰に向けて言うわけでもないですが、回答をもらっても
返事をする気がないなら、最初から質問しないでね。

No. 1348 # ミング [E-mail] 2000/11/12 (日) 00:33:45
沢山の回答、どうもありがとうございます。
あとお礼が遅くなってどうもすいません。
試してみてから出そうと思っていたのですが、家にUNixがないので
月曜になってしまいます。

このページを発見して間もないのですが、これから色々質問することもある思うので、その時はまたよろしくお願いします!

Prev< No. 1332〜1348> Next  [最新発言に戻る] [過去ログ一覧]