web-dev-qa-db-ja.com

Perlのバックティック、システム、およびexecの違いは何ですか?

誰か助けてくれますか? Perlでは、次の違いは何ですか?

exec "command";

そして

system("command");

そして

print `command`;

シェルコマンドを実行する他の方法もありますか?

226
rlbond

exec

コマンドを実行し、never return。関数内のreturnステートメントのようなものです。

コマンドが見つからない場合、execはfalseを返します。コマンドが見つかった場合、コマンドはまったく返されないため、trueを返すことはありません。 STDOUTSTDERR、またはコマンドの終了ステータスを返すことも意味がありません。これについてのドキュメントは perlfunc にあります。これは関数であるためです。

system

コマンドを実行し、コマンドが終了した後、Perlスクリプトが続行されます。

戻り値は、コマンドの終了ステータスです。それに関するドキュメントは perlfunc にあります。

バックティック

systemのようにコマンドを実行すると、コマンドが終了した後もPerlスクリプトが継続されます。

systemとは反対に、戻り値はコマンドのSTDOUTです。 qx//はバックティックと同等です。 perlopsystemitとは異なり、演算子であるため、 exec でドキュメントを見つけることができます。


他の方法

上記から欠落しているのは、コマンドを非同期的に実行する方法です。つまり、Perlスクリプトとコマンドが同時に実行されます。これは open で実現できます。これにより、コマンドのSTDOUT/STDERRを読み取り、STDINに書き込むことができます。ただし、プラットフォームに依存します。

このタスクを容易にするモジュールもいくつかあります。 IPC::Open2IPC::Open3IPC::Runがあり、Windowsを使用している場合はWin32::Process::Createもあります。

255

一般的に、やりたいことに応じて、systemopenIPC::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: $!";

IPC :: Open2 :プロセスを実行し、STDINとSTDOUTの両方へのパイプを作成します

プロセスの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>;

IPC :: Open :プロセスを実行し、STDIN、STDOUT、およびSTDERRへのパイプを作成します

プロセスの3つの標準ファイルハンドルをすべてキャプチャする必要がある場合は、IPC::Open3を使用します。私は例を書きますが、IPC :: Open2とほとんど同じように機能しますが、引数と3番目のファイルハンドルの順序が少し異なります。

164
Chas. Owens

最初にマニュアルを引用します。

perldoc exec()

Exec関数は、システムコマンドを実行し、never return-systemの代わりにexec返したい場合

perldoc system()

Exec LISTとまったく同じことを行いますが、最初にフォークが行われ、親プロセスは子プロセスの完了を待ちます。

execおよびsystemとは対照的に、バックティックは戻り値ではなく、収集されたSTDOUTを提供します。

perldoc `String`

(場合によっては)補間され、/ bin/shまたは同等のコマンドでシステムコマンドとして実行される文字列。シェルのワイルドカード、パイプ、およびリダイレクトが尊重されます。コマンドの収集された標準出力が返されます;標準エラーは影響を受けません。


代替案:

STDOUT、STDERR、またはリターンコードを取得するより複雑なシナリオでは、 IPC :: Open2IPC :: 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 も見る価値があります…

17

Perlのバックティック(`)、system、およびexecの違いは何ですか?

exec -> exec "command"; ,
system -> system("command"); and 
backticks -> print `command`;

exec

execはコマンドを実行し、Perlスクリプトを再開しません。 returnステートメントが関数に対してであるように、それはスクリプトに対してです。

コマンドが見つからない場合、execはfalseを返します。コマンドが見つかった場合、まったく返されないため、trueを返すことはありません。 STDOUTSTDERR、またはコマンドの終了ステータスを返すことも意味がありません。それについてのドキュメントは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に割り当てられますが、割り当てられた値は0lsからの終了コード)です。

ここでは、最初の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ステートメントによって印刷されます。

9
linuxtestside

「exec」と「system」の違いは、execが現在のプログラムを「command」に置き換え、プログラムに決して戻らないことです。一方、システムは「コマンド」を分岐して実行し、実行が終了すると「コマンド」の終了ステータスを返します。バックティックは「コマンド」を実行し、その標準出力を表す文字列を返します(画面に出力されるものは何でも)

Popenを使用してシェルコマンドを実行することもできますが、典型的なシェルコマンドへの透過的なアクセスを可能にする「シェルを使用」というシェルモジュールがあると思います。

それがあなたのためにそれを明確にすることを願っています。

2
Shane C. Mason