1. 概要

Linuxで複数のコマンドのシーケンスを実行して(コマンドチェーン)、結果を連結して非常に特定のタスクを実行する必要がある場合があります。 たとえば、ファイルをダウンロードして解凍し、圧縮されたファイルを削除します。

この簡単なチュートリアルでは、Linuxでbashを使用してコマンドをシリアル化するいくつかの方法を説明します。 それらのいくつかがすでに実行されている場合でも。

2. インラインコマンドチェーン

bash 構文は、ユーザーに大きな柔軟性とパワーをもたらします。 最も多様な任務を実行するために、コマンドの長いシーケンスを作成できます。

<command1> <arguments1> <chaining operator> <command2> <arguments2> ...

いくつかの連鎖操作があります。最もよく使用される操作を見てみましょう。

  • ; (セミコロン)–右側のコマンドは、結果に関係なく、左側のコマンドの後に実行されます
  • (アンパサンド)–左側のコマンドはバックグラウンドで実行され、右側のコマンドはすぐに開始されます
  • | (パイプ)–左側のコマンドの標準出力が右側のコマンドの標準入力にパイプされます
  • && (AND)–左側のコマンドが成功した場合、右側のコマンドが実行されます(ゼロ戻りコード)
  • || (OR)–左側のコマンドが成功しなかった場合、右側のコマンドが実行されます(ゼロ以外の戻りコード)*

括弧で囲まれたステートメントチェーンを使用して、サブシェルで実行されるブロックを定義することもできます。

( <command1> && <command2> ) & ( <command3> && <command4> ) &

これにより、2つのコマンドシーケンスが並行して実行されます。 それぞれにおいて、最初のコマンド結果は最後を条件付けます。

3. すでに実行中のプロセスを使用したコマンドチェーン

wait プログラムを使用して、すでに実行されているコマンドの後にコマンドを実行する方法を見てみましょう。 このユーティリティは、同じ名前のシステムコールのラッパーです。

それはのリストを受け取ります pids (プロセス識別番号)を引数として。 その結果、すべてのプロセスが終了するまでシェルがハングします 。 引数が通知されない場合は、現在のシェルのすべてのバックグラウンドプロセスを待機します。

実行中のプロセスpidがわからない場合は、pidofコマンドを使用して、同じ名前で実行中のすべてのプロセスのpidを取得できます。 たとえば、3つのバックグラウンド10秒間のスリープを開始し、その後それらを待ちます。

$ sleep 10 &
[1] 26176
$ sleep 10 &
[2] 26178
$ sleep 10 &
[3] 26179
$ wait $(pidof sleep) && echo Waited for 3 10-second sleeps
[1]   Done                    sleep 10
[2]-  Done                    sleep 10
[3]+  Done                    sleep 10
Waited for 3 10-second sleeps

pidofの同じ結果は、ps、grep、tr&cutの助けを借りていくつかのコマンドチェーンを使用して達成できます 。 キックのためだけに、それはこのようになります:

$ wait $(ps -ef | grep <process name> | tr -s ' ' | cut -f 2 -d ' ' ) && echo Waited for 3 10-second sleeps

上記のコマンドチェーンは、特定の結果を達成するためにコマンドをチェーンする方法のもう1つの良い例です。  構成$()は、括弧内のブロックの結果がwaitコマンドのパラメーターとして使用されることを意味します。 この場合:

  • ps -ef –すべてのプロセスを詳細とともに収集します
  • grep –から選択します ps -ef を含む行を出力します
  • tr -s” – は、 grep の出力から、重複する”(スペース)の出現を削除します。
  • cut -d” -f 2 tr から選択し、フィールド区切り文字として”(スペース)を使用して2番目のフィールドを出力します。 この場合、前のステップでリストおよびフィルタリングされたプロセスの pid

4. waitコマンドの制限

wait 戻りコードについては、waitが最後に待機していたコマンドの終了コードを戻そうとします。 ただし、実際にはそれほど信頼性は高くありません。たとえば、すでに終了したコマンドのpidを使用すると、実際の結果を返すことができません。 また、リターンコードが128より大きい場合、アプリケーションがシグナルのために終了したのか、それともそれ自体で終了したのかを知る方法はありません

最後に、待機のもう1つの制限は、同じシェルセッションで開始されたアプリケーションのみを待機できることです。 他のユーザーのプロセスを待つ必要がある場合、または他の bash セッションで開く必要がある場合は、pidofループのような他のあまり直接的な方法を使用する必要があります。

while ( pidof -q <command_to_wait> ); do sleep 1; done && <command_to_execute_after>

この例は、より一般的でそれほど強力ではない代替手段として機能します待つ。 スリープ時間に依存し、ターゲットプロセスのリターンコードを評価できません。 シェルループの反復の間にsleepを使用することは、特に使用されたコマンドの終了が速すぎる場合に、システムにCPUサイクルを適切に戻すために常に良い習慣であることに注意してください。

5. 結論

このチュートリアルでは、 bash でコマンドチェーンを使用する一般的な方法をいくつか見てきました。インラインと、他の実行中のプロセスの待機の両方です。 ただし、さらに多くのオプションと柔軟性が利用可能です。 これらの手法を、ユーザー定義の関数、スクリプトファイル、条件、またはループに関連付けることもできます。