tanaka's Programming Memo

プログラミングについてのメモ。

シェルのリダイレクトの備忘録

PHPからGitHubからプルを実行するためのコマンドに使うリダイレクトについて調べて理解できたことの備忘録です。

今回やりたかったことの最終形は以下です。

exec('/home/sakura_account/local/bin/git pull origin master 2>&1 1>/dev/null', $output, $return_var);

git pull origin masterGitHubにプルをする処理で、その後ろの2>&1 1>/dev/nullが肝心の部分です。

目次

目的

やりたいことは以下の通りです。

PHPexecコマンドは、第2引数に標準出力の結果、第3引数にステータスコードを返してくれます。以上から、標準出力は捨てて、標準エラー出力を標準出力にリダイレクトして$outputで受け取れば良さそうです。

リダイレクト

よく見る>/dev/null 2>&1とは

リダイレクトでよく見るのが>/dev/null 2>&1です。これは「標準出力(1)を/dev/nullに設定して捨てる」「標準エラー出力(2)を現在の標準出力の設定である/dev/nullに設定してやはり捨てる」という設定です。

これでは標準エラー出力も捨てられてしまうので、標準エラー出力は標準出力にリダイレクトする必要があります。

リダイレクトの要点

並べ方と設定内容があやふやだったので大混乱しました。自分的な要点は以下の2点でした。

  • リダイレクトは、左から右の順番で設定される
  • リダイレクト先は、設定時の状態が適用されて、それ以降の変更は前の設定には影響を与えない

特に2番目の理解が重要でした。

2>&1 1>/dev/nullとは

以上を踏まえた設定が2>&1 1>/dev/nullです。

  • 最初に2>&1を設定するので、標準エラー出力標準出力にリダイレクトされます
  • 次の1>/dev/nullで、標準出力を/dev/nullにリダイレクトして捨てます

標準出力を捨てる設定の方が後なので、標準エラー出力は先に設定した標準出力のままということになります。

順番を変えると?

順番を1>/dev/null 2>&1に変えるとどうなるでしょうか。リダイレクト元を省略すると、デフォルトで標準出力(1)が設定されるので、1>/dev/null>/dev/nullと同じ意味です。つまり、先に紹介したものと同じになるので何も表示されなくなります。

まとめ

設定した時点の状態のままというところがミソでした。標準エラー出力を標準出力に設定した後で、標準出力に加えた変更は、標準エラー出力には影響しないのですね。

参考URL