1つのコマンドラインで&を含む複数のコマンドを実行するにはどうすればよいですか?


12

頭痛の問題に遭遇しました。

バックグラウンドで複数のコマンドを実行するため、1つずつbashで起動します。次のように、Linuxシェルでバックグラウンドで1つのコマンドを開始するのは簡単です。

myCommand &

次のように、複数のコマンドを簡単に開始することもできます。

myCommand1 && myCommand2

または

myCommand1 ; myCommand2

しかし、バックグラウンドで複数のコマンドを実行したい場合、次のコマンド形式を試しましたが、失敗しました:

myCommand1 & && myCommand2 &

または

myCommand1 & ; myCommand2 &

どちらの形式も失敗します。&1つのコマンドラインにある複数のコマンドを実行するにはどうすればよいですか?


2
それらをスクリプトに入れて、バックグラウンドでスクリプトを実行します
パンサー



パンサー、()を使用すると、スクリプトを使用するよりもはるかに簡単にこの問題を解決できるようです。自分が望むものを作成する代わりに、まずシェル自体が提供する機能を最大限に活用してみましょう。ただし、もちろん、スクリプトを使用することでこの問題を解決することもできます。とにかくありがとう。
時計ZHONG

「tail -F <file1>> <file2>」の後に「jobs -l」を実行し、さらに「disown -h%1」を実行したい場合
-akskap

回答:


24

使用する ()。

順番に実行したい場合:

(myCommand1; myCommand2) &

または

(myCommand1 &) && (myCommand2 &)

それらを並行して実行したい場合:

myCommand1 & myCommand2 &

bashではこれも使用できます({と;の後ろのスペースは必須です):

{ myCommand1 && myCommand2; } &

3
(myCommand1 &) && (myCommand2 &)失敗しmyCommand2ても実行されますmyCommand1
テルドン

()はbashが&と&&を区別するのに役立ちます。したがって、&および&&を一緒に使用する場合は、()を使用して実行ユニットを分離します。
時計ZHONG

16

これが欲しいと思う:

myCommand1 & myCommand2 &

これが開始myCommand1され、アンパサンドが続くようにバックグラウンドに送信され、その後すぐに開始さmyCommand2れてバックグラウンドにも送信されるため、シェルが再び解放されます。

リスト

理解を深めるために、ここでコマンドによってパイプラインを置き換えることができます。

リストは、演算子の1つで区切られた1つ以上のパイプラインのシーケンスです。&&、または|| 、およびオプションで終了し ます; 、または

コマンドが制御演算子によって終了した場合、シェルはサブシェルのバックグラウンドでコマンドを実行します。シェルはコマンドが終了するまで待機せず、戻りステータスは0 です。順次実行されます。シェルは、各コマンドが順番に終了するのを待ちます。戻りステータスは、最後に実行されたコマンドの終了ステータスです。

ANDおよびORリストは、&& および ||で区切られた1つ以上のパイプラインのシーケンスです。 それぞれ制御演算子。
ソース:man bash

それを例に分けましょう。コマンドを組み合わせて、これらのいずれかでそれらを分離することにより、リストを作成できます; & && ||

command1 ; command2  # runs sequentially
command1 && command2 # runs sequentially, runs command2 only if command1 succeeds
command1 || command2 # runs sequentially, runs command2 only if command1 fails
command1 & command2  # runs simultaneously

次のいずれかでリストを終了できます; & <newline>
通常Enter、を押してコマンドまたはリストを実行します<newline>。セミコロン;は、特にスクリプトでまったく同じ目的を果たします。&ただし、アンパサンドはバックグラウンドのサブシェルでコマンドを開始し、すぐにシェルを解放します。

()括弧または中括弧{}を使用してリストをさらにグループ化できます。違いは、丸括弧はサブシェルを生成し、中括弧はサブシェルを生成しないことです。中括弧は、最初の括弧の後にスペースが必要で、閉じ括弧の前にセミコロンまたは改行が必要です。例えば:

# if c1 succeeds start a shell in the background
# and run c2 and c3 sequentially inside it
c1 && ( c2 ; c3 ) & 
# run c1 and if it succeeds c2 sequentially as a group command
# if c1 or c2 fail run c3 in the background
{ c1 && c2 ;} || c3 &

あなたがわからない、使用している場合、これは非常に複雑得ることができますtrueし、false期待通りのテストに建設が機能するかどうか:

$ { true && true ;} || echo 2
$ { true && false ;} || echo 2
2

ジョブ制御

このjobsコマンドは、実行中のバックグラウンドジョブ、または現在のシェルで最近終了したバックグラウンドジョブのリストを表示します。ジョブ制御用のキーボードショートカットとコマンドがいくつかあります。

  • Ctrl+ Zタイプは一時停止、停止する現在フォアグラウンドで実行中のプロセスの原因となる文字をそれが終了していないが、中に残ってjobsリスト
  • Ctrl+ Yタイプの中断遅れ、それは、端末から入力を読み込もうとしたときに、現在フォアグラウンドで実行中のプロセスを停止する原因となる文字を
  • fg= %必要に応じてプロセスをフォアグラウンドで開始し、次のようにプロセスを指定できます。

     %       # last process in the jobs list
     %1      # 1st process in the jobs list
     %abc    # process beginning with the string “abc”
     %?abc   # process containing the string “abc” anywhere
  • bg= %&必要に応じてプロセスをバックグラウンドで開始します:

     %&      # last process in the jobs list
     %1&     # 1st process in the jobs list
     %abc&   # process beginning with the string “abc”
     %?abc&  # process containing the string “abc” anywhere
  • wait バックグラウンドプロセスが終了するのを待ち、終了ステータスを返します。

     wait %1 # 1st process in the jobs list

    長いプロセスを開始し(jobs3番であることが明らかになった)、コンピューターが終了したときに中断しecho、プロセスが成功しなかった場合はメッセージを表示したいことを想像してください。

     wait %3 || echo failed ; systemctl suspend

しかし、&&に注意することが重要です。コマンドが返すものに依存するため、実際に呼び出すものは必ずbashが真理値と見なすものを返す必要があります。
mathreadler

@mathreadlerよくできていないユーザースクリプトについて話していない限り、終了値は非常に明確に定義され(参考文献を参照man bash)、意図したとおりに広く使用されています。
デザート

正確に言えば、ユーザースクリプトの作成に注意が必要です。それらは存在し、そのようなバグを見つけるのは苦痛です。Askubuntuでは、「@デザート」を許可していません。
mathreadler

ああ、それはあなたがそれについて言及した今、それは理にかなっています。
mathreadler
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.