bashでの2つの同時コマンドを含むCtrl-C


15

Linuxマシンのbashで2つのコマンドを同時に実行したい。したがって、私の./execute.shbashスクリプトに次のように記述します。

command 1 & command 2
echo "done"

ただし、bashスクリプトを停止してCtrl+を押したい場合はC、2番目のコマンドのみが停止します。最初のコマンドは実行を続けます。完全なbashスクリプトが停止したことを確認するにはどうすればよいですか?または、いずれにせよ、両方のコマンドを停止するにはどうすればよいですか?この場合、Ctrl+ を何度押しCてもコマンドが実行され続け、端末を閉じる必要があるためです。


フォローアップの質問を別の質問にして、ここから削除します。訪問者にとって、両方の質問が答えられたのか、それとも最初の質問だけなのかは不明です。
ゼルダ14年

回答:


17

入力した場合

command 1 & command 2

これは等しい

command 1 &
command 2

つまり、これはバックグラウンドで最初のコマンドを実行し、次にフォアグラウンドで2番目のコマンドを実行します。特に、これは、まだ実行中であっても、終了echo "done"後に印刷されることを意味します。command 2command 1

おそらく欲しい

command 1 &
command 2 &
wait
echo "done"

これにより、両方のコマンドがバックグラウンドで実行され、両方が完了するのを待ちます。


CTRL-Cを押すと、これはSIGINTシグナルをフォアグラウンドプロセス(つまりcommand 2、ご使用のバージョンまたはwait私のバージョン)にのみ送信します。

このようなトラップを設定することをお勧めします。

#!/bin/bash

trap killgroup SIGINT

killgroup(){
  echo killing...
  kill 0
}

loop(){
  echo $1
  sleep $1
  loop $1
}

loop 1 &
loop 2 &
wait

トラップを使用すると、CTRL-Cによって生成されたSIGINTシグナルがトラップされ、killgroupすべてのプロセスを強制終了する関数に置き換えられます。


ご回答ありがとうございます!ただし、フォローアップの質問があります。現在、次のスクリプトがあります。trap killgroup SIGINT killgroup(){echo killing ... kill 0} command001 command1&command2 command2が終了してもスクリプトは続行できるため、waitコマンドは省略しました。ただし、スクリプトを実行すると、コマンド1は既に開始されているようです。これを修正できますか?おかげで
maero21

command1は、command001の終了後に直接開始されます。set -xスクリプトの先頭で使用して、実行されるコマンドを印刷できます。
ミカ14年

6

スクリプトからバックグラウンドにコマンドを入力すると、PIDは画面に表示されません。$!command1のPIDをキャプチャできるように、最後のプロセスのPIDを格納する組み込み変数を使用できます。

command1 &
echo $!

command1のPIDをエコーし​​ます。

Bashは、特定のシグナルを受信したときに実行する一連のコマンドを登録するために使用できるトラップ組み込み機能も提供します。これを使用して、メインスクリプトを終了する前にSIGINTをキャッチし、command1を強制終了できます。

#!/bin/bash

onINT() {
echo "Killing command1 $command1PID too"
kill -INT "$command1PID"
exit
}

trap "onINT" SIGINT
command1 &
command1PID="$!"
comamnd2
echo Done

これで、コマンド2の実行中にヒットCtrl Cすると、command1とcommand2の両方がSIGINTに送信されます。


%nこのシェルで特定のバックグラウンドジョブを強制終了する構文も使用できます。通常kill %1、最新かつ唯一のバックグラウンドプロセスを強制終了します。バックグラウンドプロセスが多い場合jobsは、最初にリストを表示するために使用します。
9000 14年

@ 9000:はい。ただし、OPはスクリプト(./execute.sh)でコマンドを実行しているため、ジョブを機能させることは確実に問題になりますか?

@lain:確かに。スクリプトからの実行に関するポイントを逃しました。
9000 14年

5

GNU Parallelの新しいバージョンは、あなたが望むことをします:

parallel ::: "command 1" "command 2"
echo "done"

またはcommand、同じままの場合:

parallel command ::: 1 2
echo done

簡単な紹介については、紹介ビデオをご覧くださいhttps : //www.youtube.com/playlist?list=PL284C9FF2488BC6D1

チュートリアルをご覧ください(man parallel_tutorial)。あなたはそれを愛しているコマンドラインです。


1

Ctrl+はC、フロントプロセスにSIGINTシグナルを送信しますcommand2command1バックグラウンドで実行されるため、入力ストリームには関係ありません。

を入力するとcommand1 &、bashはプロセスのPIDを提供します[1234]。このプロセスを強制終了するには、を使用できますkill 1234。あなたは、両方のPIDを持っている場合今、command1およびcommand2(見てps -ef)は、使用することができますkillそれらをすべて終了させます。

kill pid1 pid2 pid3 ...

ちょっとしたコツは、両方のコマンドをバックグラウンドで実行することです:

command1 & command2 &

Bashは両方のPIDを提供し、殺される準備をします。別のトリックはcommand1、殺した後、フォアグラウンドに戻すことですcommand2

command1 & command2
# Hit Ctrl+C : command2 terminates.

fg # Bring back command1 to foreground.
# Hit Ctrl+C again, command1 terminates.

詳細はこちら:http : //linuxg.net/how-to-manage-background-and-foreground-processes/

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