誰か助けてくれますか? Perlでは、次の違いは何ですか?
exec "command";
そして
system("command");
そして
print `command`;
シェルコマンドを実行する他の方法もありますか?
コマンドを実行し、never return。関数内のreturn
ステートメントのようなものです。
コマンドが見つからない場合、exec
はfalseを返します。コマンドが見つかった場合、コマンドはまったく返されないため、trueを返すことはありません。 STDOUT
、STDERR
、またはコマンドの終了ステータスを返すことも意味がありません。これについてのドキュメントは perlfunc
にあります。これは関数であるためです。
コマンドを実行し、コマンドが終了した後、Perlスクリプトが続行されます。
戻り値は、コマンドの終了ステータスです。それに関するドキュメントは perlfunc
にあります。
system
のようにコマンドを実行すると、コマンドが終了した後もPerlスクリプトが継続されます。
system
とは反対に、戻り値はコマンドのSTDOUT
です。 qx//
はバックティックと同等です。 perlop
やsystem
itとは異なり、演算子であるため、 exec
でドキュメントを見つけることができます。
上記から欠落しているのは、コマンドを非同期的に実行する方法です。つまり、Perlスクリプトとコマンドが同時に実行されます。これは open
で実現できます。これにより、コマンドのSTDOUT
/STDERR
を読み取り、STDIN
に書き込むことができます。ただし、プラットフォームに依存します。
このタスクを容易にするモジュールもいくつかあります。 IPC::Open2
とIPC::Open3
とIPC::Run
があり、Windowsを使用している場合はWin32::Process::Create
もあります。
一般的に、やりたいことに応じて、system
、open
、IPC::Open2
、またはIPC::Open3
を使用します。 qx//
演算子は単純ですが、機能が制約されすぎているため、簡単なハック以外では非常に役立ちません。 open
の方がずっと便利です。
system
:コマンドを実行し、それが戻るのを待ちますコマンドを実行し、その出力を気にせず、コマンドが終了するまでPerlスクリプトに何もさせたくない場合は、system
を使用します。
#doesn't spawn a Shell, arguments are passed as they are
system("command", "arg1", "arg2", "arg3");
または
#spawns a Shell, arguments are interpreted by the Shell, use only if you
#want the Shell to do globbing (e.g. *.txt) for you or you want to redirect
#output
system("command arg1 arg2 arg3");
qx//
または `` :コマンドを実行し、そのSTDOUTをキャプチャしますコマンドを実行し、STDOUTに書き込む内容をキャプチャし、コマンドが終了するまでPerlスクリプトに何もさせたくない場合は、qx//
を使用します。
#arguments are always processed by the Shell
#in list context it returns the output as a list of lines
my @lines = qx/command arg1 arg2 arg3/;
#in scalar context it returns the output as one string
my $output = qx/command arg1 arg2 arg3/;
exec
:現在のプロセスを別のプロセスに置き換えます。コマンドを実行する場合、その出力を気にせず、返されるまで待ちたくない場合は、 exec
とともにfork
を使用します。 system
は本当にただ
sub my_system {
die "could not fork\n" unless defined(my $pid = fork);
return waitpid $pid, 0 if $pid; #parent waits for child
exec @_; #replace child with new process
}
waitpid
および perlipc
のマニュアルを読むこともできます。
open
:プロセスを実行し、STDINまたはSTDERRへのパイプを作成しますプロセスのSTDINにデータを書き込む場合、またはプロセスのSTDOUTからデータを読み取る場合は、open
を使用します(同時に両方ではありません)。
#read from a gzip file as if it were a normal file
open my $read_fh, "-|", "gzip", "-d", $filename
or die "could not open $filename: $!";
#write to a gzip compressed file as if were a normal file
open my $write_fh, "|-", "gzip", $filename
or die "could not open $filename: $!";
プロセスのSTDINおよびSTDOUTの読み取りと書き込みが必要な場合は、IPC::Open2
を使用します。
use IPC::Open2;
open2 my $out, my $in, "/usr/bin/bc"
or die "could not run bc";
print $in "5+6\n";
my $answer = <$out>;
プロセスの3つの標準ファイルハンドルをすべてキャプチャする必要がある場合は、IPC::Open3
を使用します。私は例を書きますが、IPC :: Open2とほとんど同じように機能しますが、引数と3番目のファイルハンドルの順序が少し異なります。
Exec関数は、システムコマンドを実行し、never return-systemの代わりにexec返したい場合
Exec LISTとまったく同じことを行いますが、最初にフォークが行われ、親プロセスは子プロセスの完了を待ちます。
execおよびsystemとは対照的に、バックティックは戻り値ではなく、収集されたSTDOUTを提供します。
(場合によっては)補間され、/ bin/shまたは同等のコマンドでシステムコマンドとして実行される文字列。シェルのワイルドカード、パイプ、およびリダイレクトが尊重されます。コマンドの収集された標準出力が返されます;標準エラーは影響を受けません。
STDOUT、STDERR、またはリターンコードを取得するより複雑なシナリオでは、 IPC :: Open2 や IPC :: Open などのよく知られた標準モジュールを使用できます。
例:
use IPC::Open2;
my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'some', 'cmd', 'and', 'args');
waitpid( $pid, 0 );
my $child_exit_status = $? >> 8;
最後に、CPANからの IPC :: Run も見る価値があります…
Perlのバックティック(`
)、system
、およびexec
の違いは何ですか?
exec -> exec "command"; ,
system -> system("command"); and
backticks -> print `command`;
exec
exec
はコマンドを実行し、Perlスクリプトを再開しません。 return
ステートメントが関数に対してであるように、それはスクリプトに対してです。
コマンドが見つからない場合、exec
はfalseを返します。コマンドが見つかった場合、まったく返されないため、trueを返すことはありません。 STDOUT
、STDERR
、またはコマンドの終了ステータスを返すことも意味がありません。それについてのドキュメントはperlfuncにあります。これは関数であるためです。
例えば。:
#!/usr/bin/Perl
print "Need to start exec command";
my $data2 = exec('ls');
print "Now END exec command";
print "Hello $data2\n\n";
上記のコードには、3つのprint
ステートメントがありますが、exec
がスクリプトを離れるため、最初のprintステートメントのみが実行されます。また、exec
コマンドの出力はどの変数にも割り当てられていません。
ここでは、最初のprint
ステートメントの出力のみを取得し、標準出力でls
コマンドを実行しています。
system
system
はコマンドを実行し、コマンドの終了後にPerlスクリプトが再開されます。戻り値は、コマンドの終了ステータスです。それに関するドキュメントはperlfuncにあります。
例えば。:
#!/usr/bin/Perl
print "Need to start system command";
my $data2 = system('ls');
print "Now END system command";
print "Hello $data2\n\n";
上記のコードには、3つのprint
ステートメントがあります。 system
コマンドの後にスクリプトが再開されると、3つのprintステートメントがすべて実行されます。
また、system
の実行結果はdata2
に割り当てられますが、割り当てられた値は0
(ls
からの終了コード)です。
ここでは、最初のprint
ステートメントの出力を取得してから、ls
コマンドの出力を取得し、その後に標準出力で最後の2つのprint
ステートメントの出力を取得しています。
`
)system
と同様に、コマンドをバックティックで囲むと、そのコマンドが実行され、コマンドの終了後にPerlスクリプトが再開されます。 system
とは対照的に、戻り値はコマンドのSTDOUT
です。 qx//
はバックティックと同等です。これについてのドキュメントはperlopにあります。システムやexec
とは異なり、演算子です。
例えば。:
#!/usr/bin/Perl
print "Need to start backticks command";
my $data2 = `ls`;
print "Now END system command";
print "Hello $data2\n\n";
上記のコードには、3つのprint
ステートメントがあり、3つすべてが実行されています。 ls
の出力は標準出力に直接送られるのではなく、変数data2
に割り当てられてから、最終的なprintステートメントによって印刷されます。
「exec」と「system」の違いは、execが現在のプログラムを「command」に置き換え、プログラムに決して戻らないことです。一方、システムは「コマンド」を分岐して実行し、実行が終了すると「コマンド」の終了ステータスを返します。バックティックは「コマンド」を実行し、その標準出力を表す文字列を返します(画面に出力されるものは何でも)
Popenを使用してシェルコマンドを実行することもできますが、典型的なシェルコマンドへの透過的なアクセスを可能にする「シェルを使用」というシェルモジュールがあると思います。
それがあなたのためにそれを明確にすることを願っています。