2016-07-26 12 views
2

私はこのシナリオに遭遇したことがありません。私は、シェルコマンドからif/elseステートメントを発行しようとしていますが、perl内です。私はシステムとエグゼクティブを成功させようとしました。私はそれが正常に動作シェルでコマンドif ! dpkg -l curl &> /dev/null; then apt-get install curl -y; fiを実行しますが、perlのから、それを実行するとif部分をスキップし、それをインストールする右に行く場合にはここでコードperlからif elseシェルコマンドを実行する

if ($os eq 'Ubuntu'){ 
    system('if ! dpkg -l curl &> /dev/null; then apt-get install curl -y; fi'); 
    foreach my $mod (keys %deb){ 
     eval "use $mod"; 
     if([email protected]){ 
      system("apt-get install $deb{$mod} -y"); 
      eval "use $mod"; 
     } 
    } 
} 

のサンプルです。

+0

'system( '/ bin/sh -c if!dpkg ...')' –

+0

のように、Perlに依存する代わりに明示的にシェルを呼び出す必要があるかもしれません( '/ bin/sh -c if if dpkg ...')は私を近づけますが、今は不平を言っています!:1:!:構文エラー:予期せぬファイルの終わりです。たぶん私はいくつかの文字を逃れる必要がありますか? –

答えて

4

ifは問題なく機能します。

$ perl -e'system("if ! true ; then echo ok ; fi")' 

$ perl -e'system("if ! false ; then echo ok ; fi")' 
ok 

ただし、問題があります。あなたが投稿したのはbashコマンドですが、system(EXPR)system('/bin/sh', '-c', EXPR)の略です。単にトリックを行う必要があります

system('/bin/bash', '-c', EXPR) 

system(EXPR) 

を交換します。

0

問題は少し問題があるようでしたので、私はそれを解決する別の方法を行った。ここで私はあなたがif構文の詳細に入る回避し、またそれを||代わりの否定を使用してビットを簡素化することができます私は同じ結果

if ($os eq 'Ubuntu'){ 
    my $check = `dpkg --get-selections | grep "^curl *" | awk '{print \$1}'`; 
    if(!$check){ system('apt-get install curl -y > /dev/null'); } 
     foreach my $mod (keys %deb){ 
      eval "use $mod"; 
      if([email protected]){ 
      system("apt-get install $deb{$mod} -y"); 
      eval "use $mod"; 
     } 
    } 
} 
2

を与えるやってしまったものです。コマンドライン

perl -we 'system("rpm -q NO_PACK &> /dev/null || echo \"install package\"")' 

でそれを試してみるために、私は唯一のため、今RHEL上rpmをテストすることができます。しかし、RHEL上で、私はあまりにも

perl -we 'system("if ! rpm -q NO >& /dev/null ; then echo install; fi")' 

、これは正常に動作するために見つけることは(自身がshへのリンクである)Ubuntuでdashあるsystemによって呼び出されたシェル、と競合するコマンドで構文です。これに関するコメントのためにikegamiThisSuitIsBlackNotに感謝します。具体的には、リダイレクト&>は動作しません。具体的にはbashの機能です。そして、あなたは/dev/nullSTDOUTストリームを送信し、STDOUT(1)shbashへのリンクですRHELシステムで

system('dpkg -l curl > /dev/null 2>&1 || apt-get install curl -y'); 

を行く同じ場所にSTDERRストリーム(2)をリダイレクトする一般的な> /dev/null 2>&1に変更することができ、したがって&>が動作します。 2&>1リダイレクトも同様に機能することに注意してください。しかし、私の意見では、より良い解決策は、使用するシェルを指定することです。

systemは、リストに引数を指定することで、シェルを起動することができます。ではありません。最初の引数として与えられたプログラムはシェルの起動なしに直接実行され、リストの残りの部分はそれに渡されます。これは、リスト内の最初の引数としてそのシェルを指定できるので、コマンドを実行するために正しいシェルを取得する方法です。これは、答えにikegamiで示されています。

+0

ありがとう、私はそれを将来の実装のために試してみます –

+0

これはまだ有効なbourneシェルコマンドではありません。 – ikegami

+0

@ikegamiコメントありがとうございました - これは難解でした。私は明確な 'if 'ステートメントでなければならないものを試しましたが、展開のために'! 'を使っていました。私は '[...]'を試みたが、私は 'test'も動かすことができなかった。一方、これは 'bash'からのターミナルと上記の1つのライナーとして動作します。また、私はなぜそれが有効でないのか分かりません - 私は 'rpm'が1/0で終了すると思うので、' dpkg'もそうでしょう。条件として使用することはできず、副作用として実行できますか? – zdim

関連する問題