2008-08-19 8 views
10

Perlでは、system()または ``(backticks)を使ってシステムコマンドを実行できます。コマンドの出力を変数に取り込むことさえできます。ただし、プログラムの実行をバックグラウンドで非表示にして、スクリプトを実行している人には表示されないようにします。Perlのsystem()は、実行中のコマンドをどのように表示できますか?

通常これは便利ですが、時には裏で何が起こっているのかを見たい場合もあります。実行されたコマンドが端末に印刷され、それらのプログラムの出力が端末に出力されるようにするにはどうすればよいですか?これは "@echo on"に相当する.batになります。

答えて

8

私が分かるように、system()はコマンドの結果を出力しますが、割り当てません。例えば。

[[email protected] /]$ perl -e '$ls = system("ls"); print "Result: $ls\n"' 
bin dev home lost+found misc net proc sbin  srv System tools var 
boot etc lib media  mnt opt root selinux sys tmp  usr 
Result: 0 

バッククォートは、それを印刷コマンドの出力をキャプチャしません。など

[[email protected] /]$ perl -e '$ls = `ls`; print "Result: $ls\n"' 
Result: bin 
boot 
dev 
etc 
home 
lib 

...

更新

あなたがされているコマンドの名前を印刷したい場合system() 'dでも、私は Ruddのアプローチが良いと思います。統合のためにここでは繰り返さ:

sub execute { 
    my $cmd = shift; 
    print "$cmd\n"; 
    system($cmd); 
} 

my $cmd = $ARGV[0]; 
execute($cmd); 
4

代わりにオープンを使用してください。次に、コマンドの出力をキャプチャできます。

open(LS,"|ls"); 
print LS; 
18

私はこれを行うには、任意のデフォルトの方法を知りませんが、あなたはあなたのためにそれを行うためのサブルーチンを定義することができます。

sub execute { 
    my $cmd = shift; 
    print "$cmd\n"; 
    system($cmd); 
} 

my $cmd = $ARGV[0]; 
execute($cmd); 

そしてアクションでそれを参照してください:

pbook:~/foo rudd$ perl foo.pl ls 
ls 
file1 file2 foo.pl 
2

うん、さまざまな人々がこの異なる方法にどのように答えているか興味深い。 mkDaniel Foneは、コマンドの標準出力を表示/操作したいと解釈しています(いずれのソリューションもstderr fwiwをキャプチャしません)。 Ruddが近づいたと思う。 Ruddの応答でできることの1つは、組み込みのsystem()コマンドを独自のバージョンで覆い、execute()コマンドを使用するために既存のコードを書き直す必要がないようにすることです。ラッドのポストからの彼の実行()サブを使用して

、あなたのコードの上部に次のようなものかもしれない:

if ($DEBUG) { 
    *{"CORE::GLOBAL::system"} = \&{"main::execute"}; 
} 

を、私はそれが動作すると思いますが、私は、これはブードゥー教です認めざるを得ない、それがされています私はこのコードを書いてからしばらくしています。

# importing into either the calling or global namespace _must_ be 
    # done from import(). Doing it elsewhere will not have desired results. 
    delete($opts{handle_system}); 
    if ($do_system) { 
    if ($do_system eq 'local') { 
     *{"$callpkg\::system"} = \&{"$_package\::system"}; 
    } else { 
     *{"CORE::GLOBAL::system"} = \&{"$_package\::system"}; 
    } 
    } 
+0

グローバル 'system'コマンドを交換して大きな問題は' system'がで複製することができない複雑なプロトタイプを持っているということですユーザーが指定したプロトタイプシステム。その結果、 'system'をあなたのカスタムバージョンに置き換えると、いくつかのコードが機能しなくなります。 – cjm

1

の回答に記載他人と結合する別の技術は、teeコマンドを使用することです。ここでは、モジュールのロード時にローカル(呼び出し名前空間)またはグローバルレベルで呼び出して、私はシステムを傍受するために数年前に書いたコードです。たとえば:

open(F, "ls | tee /dev/tty |"); 
while (<F>) { 
    print length($_), "\n"; 
} 
close(F); 

これは、両方(tee /dev/ttyの結果として)、現在のディレクトリ内のファイルをプリントアウトし、また読んで各ファイル名の長さをプリントアウト。

4

は、ここでそれは結果を印刷し、それらを返します実行更新です:

sub execute { 
    my $cmd = shift; 
    print "$cmd\n"; 
    my $ret = `$cmd`; 
    print $ret; 
    return $ret; 
} 
関連する問題