2016-09-09 27 views
1

パイプコマンドを使用してシステムシェルを呼び出すPHPスクリプトがあります。私たちは、バックアップスクリプトの話をしている。この場合、(しかし、それは何もすることができ、私は終了ステータスについて特に求めている!):PHPでパイプコマンドの終了ステータスを取得

exec(
    "mysqldump --user=$u --password=$p --host=$h --port=$p $db | gzip -9 > backup.sql.gz", 
    $out, 
    $status 
); 

今私はmysqldumpをコマンドでエラーが生じたかどうかを知りたいです、エラーを強制しても、の変数には常に0が含まれているようです。これは、の第2のコマンド(この場合はgzip)の終了コードのようです。私はの最初のコマンドの終了ステータスをPHPで見ることができます。

+0

シリーズでそれらを実行しないのはなぜ?その後、簡単に伝えることができます。 – Machavity

+0

@ e4c5、どのように質問が*類似しているのですか?バックアップについてではなく、終了ステータスについて質問しています。サンプルスクリプトはちょうど**データベースのバックアップスクリプトとなりました。 – aross

+0

@Machavity、私は巨大な中間ファイルを望んでいません。 – aross

答えて

3

Bashの内部配列PIPESTATUSから少し助けが必要です。これは、パイプ内の各コマンドの終了ステータスを保持します。最初のコマンドの終了ステータスを探しているので、PIPESTATUS[0]に対処します。ですから、コードは次のようになります:

exec(
    "bash -c 'mysqldump --user=$u --password=$p --host=$h --port=$p $db | gzip -9 > backup.sql.gz; exit \${PIPESTATUS[0]}'", 
    $out, 
    $status 
); 

注、これはexec()コールの全体的な終了ステータスを変更し、あなたはコマンドの長いチェーンの失敗をキャッチしたい場合は、追加のコードが必要となります。

+0

すごく、ありがとう。これはまさに私が探しているものです。残っているのは2つだけです:終了ステータスの配列*を得ることは可能ですか?あなたがそれらを出力してから出力の最後の行を取り出して終了ステータスを意味するのでなければ、そうは思いません。私は正しい?もう一つは、bash以外のシェルでこれを動作させる方法です(私には難しい要件ではありませんが、使い方が分かればいいと思います)。 – aross

+0

はい、終了ステータスアレイを終了ステータスではなく「出力」にする必要があります。 'PIPESTATUS'はBashの組み込み関数ですが、zshもそれを持っていると思います。私は、他のシェルが行うとは思わない。だから、あなたはそれをするために何か他の方法を探す必要があります。 –

0

私は、出口ステータスをとするより汎用的な解決策を考えました。パイプ内の各コマンドはPHPで利用可能です。もちろん、$PIPESTATUSのシェルが必要です(これは平文shを除く)。

// The command with pipes. 
$command = 'command1 | command2 | echo Test | gzip -9 -f'; 

// Execute the command. The overall exit code is in $exitStatus. 
exec(
    $command . '; echo -e "\n"${PIPESTATUS[*]}', 
    $out, 
    $exitStatus 
); 

// Get the exit statuses and remove them from the output. 
$pipeStatus = explode(' ', array_pop($out)); 

print_r([$pipeStatus, $out]); 
// [ 
// [ 
//  "127", 
//  "127", 
//  "0", 
//  "0", 
// ], 
// [ 
//  b"\x1F‹\x089fÙW\x02I-.á\x02Â\x1Axú\x05", 
// ], 
// ] 

少しシンプルなバリアントあなたはパイプで連結されたコマンドは改行で終了します確信している場合(コマンドでecho一部が異なる気づく):

// The command with pipes. 
$command = 'command1 | command2 | echo Testing things | sed s/things/stuff/'; 

// Execute the command. The overall exit code is in $exitStatus. 
exec(
    $command . '; echo ${PIPESTATUS[*]}', 
    $out, 
    $exitStatus 
); 

// Get the exit statuses and remove them from the output. 
$pipeStatus = explode(' ', array_pop($out)); 

print_r([$pipeStatus, $out]); 
// [ 
// [ 
//  "127", 
//  "127", 
//  "0", 
//  "0", 
// ], 
// [ 
//  "Testing stuff", 
// ], 
// ] 
関連する問題