web-dev-qa-db-ja.com

ターミナルウィンドウで複数のBashスクリプトを同時に実行するにはどうすればよいですか?

複数のBashスクリプト(正確には異なる変数を使用した同じスクリプト)を同時に実行する必要があります。タブの数を制御するために、それらを単一のターミナルタブにグループ化したいと思います。

スクリプトは定期的に出力され、問題がないか確認します。

それらをバックグラウンドに送ると

./script.sh 1 &
./script.sh 2 &
./script.sh 3 &
./script.sh 4

私はそれらを制御できなくなります。たとえば、私はスクリプトを終了します Ctrl+C。上記のコードを使用すると、プロセスごとにpidを見つけて強制終了できます。

上記のコードは私のメインスクリプトの内容です(たとえば、./all_scripts.sh)端末に入力するコマンドではなく。

単一の出力スクリプトとして扱いながら、同じ端末でスクリプトを実行する方法はありますか?

10
Googlebot

さまざまなメソッドとプログラムをテストした後、実用的なソリューションは GNU Parallel であることがわかりました。他の人の役に立つかもしれないので、この回答を投稿します。

GNU Parallelはこのタスク用に構築されていませんが、目的を完全に果たします。

スクリプトを次のように実行する場合

parallel -u ::: './script.sh 1' './script.sh 2' #(and so forth)

すべてのスクリプトは並行して実行されます。

-u--ungroup)フラグは、スクリプトの実行中にスクリプト出力をstdoutに送信します。

Ctrl+Cparallelジョブを強制終了し、続いて実行中のすべてのスクリプトを強制終了します。

12
Googlebot

あなたはそれらのコントロールを失うことはありません。 (最後のもの以外の)それらをバックグラウンドに送信します。

指定したコマンドチェーンを実行する場合、呼び出し./script.sh 4がフォアグラウンドになり、他のスクリプトがバックグラウンドで実行されます。入力はフォアグラウンドスクリプトに送信されます。フォアグラウンドスクリプトを一時停止するには、 CtrlZ。中断されたスクリプトをバックグラウンドに送信して実行を継続するには、bgコマンドを使用します。

あなたが持っているスクリプト(より正確には、ジョブ)とその状態を確認するには、jobsを使用します。

特定のジョブを前面に表示するには、fgとその番号(前述のjobsで報告)を%接頭辞、e。 g。 fg %2。特定のジョブを終了するには、fgを使用してフォアグラウンドに移動し、正常に終了するか、またはkillを実行します。 g。 kill -TERM %2

17
DopeGhoti

これにはtmuxを使用できます。

これは1つのタブを複数のウィンドウに分割することを意味するターミナルマルチプレクサです。

  • コマンドtmuxで開始します。
  • ペインを2つのペインに分割するには、Contr + Bの後に"または%を続けて使用します。
  • フォアグラウンドでプロセスを開始します。
  • Contr + Bに続いて矢印キーを押すプロセスを切り替えます。

これで、ターミナルの1つのタブで複数のプロセスを正常に制御できます。

特定のペインにフォーカスする(またはフォーカスを解除する)場合は、Contr + Bの後にZを続けます。

スクロールする必要がある場合は、Contr + Bに続けてQを使用し、矢印キーを使用してスクロールします(またはマウスモードをアクティブにします)。

チートシート here を見つけることができます。

そのプロセスを自動化することも可能です。

5
dan1st

出力をファイルにリダイレクトできます(プロセスごとに1つまたは結合された1つ)。書き込みが小さい場合(512バイトは安全で、おそらく4Kでも)、すべてに1つのファイルがあることは問題ではありません。小さな書き込みはアトミックです:

./script.sh 1 >output.1 2>&1 &
./script.sh 2 >output.2 2>&1 &
./script.sh 3 >output.3 2>&1 &
./script.sh 4 >output.4 2>&1 &
./script.sh 5 >output.5 2>&1 &

while wait % >/dev/null 2>&1; do : ; done

対話的に行う場合は、次のことが役立つ場合があります。(そうでなければ役に立たない)環境変数定義(BackGroundタスクIDなど)を付加することで、ジョブに簡単に対処できます。

bgtid=foo ./script.sh 1 &
[...]
kill %bgtid=foo

コマンドのプレフィックスは明確でなければなりません(つまり、bgtid=fooおよびbgtid=foobar)。

3
Hauke Laging

タスクスプーラはこのニーズに対応できます。 https://vicerveza.homeunix.net/~viric/soft/ts/article_linux_com.html

このツールは、debianおよびubuntuの 'tsp'エイリアスで見つけることができます。

1
logann2019

echo -e "1\n2\n3\n4\n" | xargs -n1 -P4 ./script.sh

これを行う別の方法です。 xargsは基本的にどのシステムでも使用でき、control-cはすべてのジョブを強制終了します。

また、(&を使用してスクリプトを呼び出す場合とは異なり、より高いレベルのbashスクリプトからこれを実行できます)

-n1オプションは、xargsに独自のプロセスで各引数を実行するように指示し、-P4オプションは、4つのプロセスを実行するように指示します。

1
Stack Tracer

ジョブをバックグラウンド化する場合、「echo $!」を使用して出力されるシェル変数最後のバックグラウンドジョブのプロセスID番号を示します。背景としてこれらのプロセス番号を保持するシェルスクリプト配列を作成し、必要に応じてプロセスを処理できます。 (つまり、「ps」で実行されているかどうかを確認したり、強制終了したりできます。)

チェックしたところ、bashで「echo $!」または「shellvar = $!」 「;」以降、改行する必要があります「&」の後には機能しません。

0
jmf7

Tmuxの興味深い機能について述べたいと思います(tmuxは、@ dan1stによってすでに優れたオプションとして提供されています)。複数のペインで同じコマンドを同時に実行する方法があります。例を示します。 echo "Fruit name is $ fruit"を2つの異なるペイン/ログイン/ホストで同時に実行したい。手順:

  1. Tmuxを起動します:tmux new-session -s myparallel
  2. CTRL-Bの後に "(これにより、ペインが2つに分割されます。さらにペインが必要な場合は繰り返します。"水平方向に分割、%は垂直方向に分割)
  3. (CTRL-Bと矢印キーを使用して)各ペインに移動して、そのペインの変数を設定します。たとえば、ペイン#1にはfruit = "Apple"があり、ペイン#2にはfruit = "orange"があります。
  4. ペインごとに変数を設定したので、次にペインを同期して、1つに入力した内容がすべてのペインにミラーリングされるようにします。これを行うコマンドはCTRL-B :setw synchronize-panes onです
  5. これで、scriptName $fruitを実行して、すべてのペインの出力を同時に表示できます。
  6. 完全を期すために、同期モードを終了するには、CTRL-B :setw synchronize-panes offと入力します
0
Hopping Bunny