2012-01-12 4 views

答えて

5

systemの最初の(1文字列の)呼び出しでは、コマンドを実行するためにシステムシェルが実行されます。特に、コマンドへの引数($var1)はシェル展開されます。

複数の引数を持つ第2のバージョンはシステムシェルをバイパスし、引き数はそれ以上のシェル処理を行いません。一般的には、これはお勧めの方法です。ただし、I/Oリダイレクトについて心配する必要があることに注意してください。それが問題であれば、最初の形式(慎重に使用する)は簡単です。あるいは、CPANを探索して、支援するモジュールを見つけることができます。

4

VS

$cmd = "/my/code.pl"; 
$status = system("$cmd $var1"); 

それは明示的に単一のコマンドライン引数として指定されたコマンドに各個別のパラメータを渡すため、後者は、(ほとんどの状況で)優れています。

以前のバージョンでは、$cmdまたは$var1に存在するスペースは、追加の(おそらく望ましくない)コマンドライン引数が送信されることになります。

例を与えるために、与えられた$cmd = "cat"$var1 = "/tmp/my test file"最初の行は、になります:

cat /tmp/my test file # three parameters 

と第二は与えるだろう:

cat "/tmp/my test file" # one parameter 

だから最初のバージョンが2でファイル名を壊します(おそらく「ファイルが見つかりません」というエラーを生成します)、2番目のバージョンでは$var1がそのまま1つのパラメータとして保持されます。

コマンドの出力(たとえば1> logfile 2>&1)、またはシェルの他の機能(グロビング、パイプなど)をリダイレクトする必要がある場合は、最初のバージョンを使用する必要があります。

+0

あなたの言うことは正しいですが、' echo'の例は悪いの...どちらかの方法で動作します。 –

+0

私は$ status = system( "$ cmd $ var1 $ var2")を持っています。第2の選択肢はどのように見えますか? – user11496

+0

@BrianRoachええ、それは私が言ったことです! – Alnitak

2

から:引数処理は、引数の数に応じて変化するhttp://perldoc.perl.org/functions/system.html

注意。 LISTに複数の引数がある場合、またはLISTが複数の値を持つ配列である場合、残りのリストによって指定された引数を持つリストの最初の要素によって与えられたプログラムを開始します。スカラー引数が1つしかない場合は、引数にシェルメタキャラクタがあるかどうかチェックされ、存在する場合は引数全体がシステムのコマンドシェルに渡されます(これはUnixプラットフォームでは/ bin/sh -cですが、他のプラットフォーム)。引数にシェルのメタキャラクタがない場合、それは単語に分割され、execvpに直接渡されます。これはより効率的です。

これはシェルが必要な場合(たとえば、あなたが例えばパイプ|、例えば./someprog | wcを使用するつもりだ)あなたの例では、最初のメソッドを使用する必要があることを意味します。

関連する問題