複数のbashスクリプトを呼び出して、順番にではなく並行して実行する


19

:私は3つ(またはそれ以上)のbashスクリプトを持っていると仮定しscript1.shscript2.shscript3.sh。これら3つすべてのスクリプトを呼び出して、並行して実行したいと思います。これを行う1つの方法は、次のコマンドを実行することです。

nohup bash script1.sh &
nohup bash script2.sh &
nohup bash script3.sh &

(一般に、スクリプトの終了には数時間または数日かかる可能性があるためnohup、コンソールが閉じても実行し続けるように使用したいと思います。)

しかし、これら3つのコマンドを1 回の呼び出しで並行して実行する方法はありますか?

私は次のようなものを考えていました

nohup bash script{1..3}.sh &

しかし、これは、ではなく、、、およびを順番に実行するようscript1.shに見えます。script2.shscript3.sh


2
「シングルコール」とはどういう意味ですか?
jw013 14年

1
ユースケースは何ですか?開始するスクリプトは100万個ありますか?
l0b0 14年

@ jw013つまり、単一の短い行コマンドのようなものです。起動するスクリプトが100個ある場合、100回入力するのではなく、何か短い(nohup bash script{1..100}.sh &またはなどfor i in {1..100}; do nohup bash script{1..100} &; done)を入力できるようにしますnohup bash script*.sh &
アンドリュー14年

1
スクリプトに有用な出力がある場合:コンソールの問題を解決し、出力(および入力)へのアクセスを維持するために、スクリプトを内screen(またはtmux)で開始することもできます。
ホークレイジング14年

1
これら3つのコマンドすべてを同じ行に入力することを妨げるものは何もありません。nohup ... & nohup ... & nohup ... &。代わりに、各スクリプト名を個別に入力せずにすべてのスクリプトを実行することを意味する場合は、単純なループで実行します。
jw013 14年

回答:



14

より良い方法は、GNU Parallelを使用することです。GNUパラレルは単純であり、それを使用すると、ジョブをより細かく制御して、並行して実行するジョブの数を制御できます。

以下のコマンドでscript{1..3}.shは、展開され、引数としてbash並行して送信されます。ここで-j0は、できるだけ多くのジョブを実行する必要があることを示しています。デフォルトでparallelは、1つのCPUコアに対して1つのジョブを実行します。

$ parallel -j0 bash :::: <(ls script{1..3}.sh)

また、使用してみることができます

$ parallel -j0 bash ::: script{1..3}.sh

エラーメッセージが表示された場合、2番目のメソッドの実行中に--tollefオプションが設定され/etc/parallel/config、削除する必要があり、すべてが正常に機能することを意味します。

あなたは読むことができGNU Parallelsmanページをここでより豊かなオプションについて。

また、リモートマシンからジョブを実行している場合は、screenネットワークの問題によりセッションが閉じられないように使用することをお勧めします。nohupasは最近のバージョンのbashに付属してhuponexitおりoff、これにより、親シェルHUPが終了中に子にシグナルを送信できなくなります。設定されていない場合は

$ shopt -u huponexit  

bashシェルparallel -j0 bash :::: <(ls script{1..3}.sh)をに減らすことができるので、使用する場合parallel -j0 bash :::: script{1..3}.sh、いいえ?
iruvar

いいえ: '::::'を並列で使用する場合、引数はコマンド自体ではなく、実行するコマンドを含むファイルであることを意味します。ここでは、プロセス置換を使用して、ファイル記述子内のスクリプト名をリダイレクトしています。
カンナンモハン14

えーと。その場合はなぜparallel -j0 bash ::: script{1..3}.shですか?
iruvar 14年

それはだbash ::: script{1..3}.shに渡されるparallel、ではありません::: script{1..3}.sh。これが最初に展開する必要がありますので、 parallel bash ::: script1.sh script2.sh script3.shシェル、その後でparallelの呼び出しbash script1.shbash script2.shbash script3.sh。私はそれを試してみました
iruvar

1
いいえ、私は混乱していません、私が述べているのは、OPの問題がよりよく解決されているということですparallel -j0 bash ::: script{1..3}.sh-これは::::、プロセス置換の必要性を回避するため、アプローチよりも優れています。また、lsの出力を解析することは落とし穴に乗っている
iruvar

9

また、xargs複数のスクリプトを並行して実行するために使用できます。

$ ls script{1..5}.sh|xargs -n 1 -P 0 bash

ここで、各スクリプトは引数として個別にbashに渡されます。-P 0並列プロセスの数を可能な限り多くできることを示します。bash defaultを使用する方が安全ですjob control feature (&)


5

一行ソリューション:

$ nohup bash script1.sh & nohup bash script2.sh & nohup bash script3.sh &

面倒なことはせず、ラッパースクリプトを使用します。

$ cat script.sh
#!/usr/bin/env bash
script1.sh &
script2.sh &
script3.sh &
$ nohup script.sh &

またはそれらをループします:

for script in dir/*.sh
do
    nohup bash "$script" &
done

2

タイピングの労力を節約したい場合

eval "nohup bash "script{1..3}.sh" &"

または考え直して、多分そうではない


1

このツールをチェックアウトします:https : //github.com/wagoodman/bashful

あなたが持っているmytasks.yamlと言います

tasks:
    - name: A title for some tasks
      parallel-tasks:
        - cmd: ./script1.sh
        - cmd: ./script2.sh -x an-arg
        - cmd: ./script3.sh -y some-other-arg

そして、あなたはそれを次のように実行します:

nohup bashful run mytasks.yaml

スクリプトは、垂直プログレスバーと並行して実行されます(以前に実行したことがあり、時間が確定的である場合は、+ eta)。ここで指定された3つ以上のタスクを実行し始める場合、並行して実行するタスクの数を微調整できます。

config:
    max-parallel-commands: 6
tasks:
    ...

免責事項:私は著者です。



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