xargsを使用してプログラムを並行して実行する


86

私は現在、現在のスクリプトを持っています。

#!/bin/bash
# script.sh

for i in {0..99}; do
   script-to-run.sh input/ output/ $i
done

xargsを使用して並行して実行したいと思います。私が試してみました

script.sh | xargs -P8

ただし、上記の実行は一度に1回だけ実行されます。-n8でも運がありません。スクリプトのforループで実行される行の最後に&を追加すると、スクリプトを一度に99回実行しようとします。一度に8つだけ、合計100までループを実行するにはどうすればよいですか。


それは私が最初にやりたかったことですが、私はWindowsを使用しているため、xargsに頼らなければなりませんでした。WindowsでGNUParallelを実行できませんでした
Olivier

そのスクリプトはそれ自体を呼び出していますか、それともここで尋ねたときに名前を混乱させましたか?
Etan Reisner 2015

申し訳ありませんが、別のスクリプトを呼び出す必要があります。修正します
Olivier

stackoverflow.com/questions/3321738/…への回答はここに関連しています。
Etan Reisner 2015

回答:


129

xargsマニュアルページから:

このマニュアルページには、GNUバージョンのxargsが記載されています。xargsは、空白(二重引用符または一重引用符または円記号で保護できます)または改行で区切られた標準入力から項目を読み取り、コマンド(デフォルトは/ bin / echo)を1回以上実行します。標準入力から読み取られた項目による。標準入力の空白行は無視されます。

つまり、この例でxargsは、スクリプトからのすべての出力を待機して収集してから、を実行していecho <that output>ます。それほど便利なものでも、あなたが望んでいたものでもありません。

-n引数には、入力から多くの項目は、(ここでは並列処理について、それ自体で、何を)実行していない取得し、各コマンドで使用する方法です。

あなたがやりたいxargsことをするために、あなたはこのような何かをする必要があるでしょう(テストされていない):

printf %s\\n {0..99} | xargs -n 1 -P 8 script-to-run.sh input/ output/

これはこのように故障します。

  • printf %s\\n {0..99}-行ごとに1つの番号をからに出力099ます。
  • 実行 xargs
    • 実行コマンドラインごとに最大1つの引数を取る
    • 一度に最大8つのプロセスを実行ます

8
実際には、引数を別々の行に置く必要はありません。xargsの単語分割。したがってecho {0..99} |、同様に機能します。<<<{0..99}うまくいかないようです。中<<<word括弧を拡張する単語として文書化されていますが、私が手元にあるどのバージョンのbashでもそうはなりません。
rici 2015

1
@riciはドキュメントのバグのように見えます。特に、ヒアドキュメントのドキュメントで、チルダの拡張については言及されていませんが(クイックテストでも発生しません)、ブレースの拡張について言及されていません(発生しません)。のためです<<が、<<<そうします*shrug*)。ヒアドキュメントとヒア文字列で発生する拡張と発生しない拡張は、私の考えでは少し奇妙です。
Etan Reisner 2015

1
改行などを使用して、さまざまな実行から結果をどのように分離できますか?
nirvana-msu 2017年

4
デモ:time head -12 <(yes "1") | xargs -n1 -P4 sleep12個のsleep 1コマンド、4個の並列コマンドを実行します。コマンドには3秒かかります。
ウォルター・A

66

GNU Parallelを使用すると、次のことができます。

parallel script-to-run.sh input/ output/ {} ::: {0..99}

CPUコアごとに1つのジョブを実行したくない-P8場合は、追加します。

反対xargsに、入力にスペース、 '、または "が含まれている場合でも、正しいことを実行します(ただし、ここではそうではありません)。また、異なるジョブからの出力が混在しないようにするため、出力を使用すると、 2つの異なる仕事から半列にならないことが保証されています。

GNU Parallelは一般的な並列処理機能であり、同じマシンまたはsshにアクセスできる複数のマシンでジョブを簡単に並列実行できます。

4つのCPUで実行する32の異なるジョブがある場合、並列化する簡単な方法は、各CPUで8つのジョブを実行することです。

簡単なスケジューリング

代わりに、GNU Parallelは、終了時に新しいプロセスを生成します。つまり、CPUをアクティブに保ち、時間を節約します。

GNU並列スケジューリング

インストール

GNU Parallelがディストリビューション用にパッケージ化されていない場合は、ルートアクセスを必要としない個人インストールを行うことができます。これを行うことにより、10秒で実行できます。

$ (wget -O - pi.dk/3 || lynx -source pi.dk/3 || curl pi.dk/3/ || \
   fetch -o - http://pi.dk/3 ) > install.sh
$ sha1sum install.sh | grep 67bd7bc7dc20aff99eb8f1266574dadb
12345678 67bd7bc7 dc20aff9 9eb8f126 6574dadb
$ md5sum install.sh | grep b7a15cdbb07fb6e11b0338577bc1780f
b7a15cdb b07fb6e1 1b033857 7bc1780f
$ sha512sum install.sh | grep 186000b62b66969d7506ca4f885e0c80e02a22444
6f25960b d4b90cf6 ba5b76de c1acdf39 f3d24249 72930394 a4164351 93a7668d
21ff9839 6f920be5 186000b6 2b66969d 7506ca4f 885e0c80 e02a2244 40e8a43f
$ bash install.sh

その他のインストールオプションについては、http://git.savannah.gnu.org/cgit/parallel.git/tree/READMEを参照してください。

もっと詳しく知る

その他の例を参照してください:http//www.gnu.org/software/parallel/man.html

イントロビデオを見る:https//www.youtube.com/playlist?list = PL284C9FF2488BC6D1

チュートリアルをウォークスルーしますhttp//www.gnu.org/software/parallel/parallel_tutorial.html

サポートを受けるためにメーリングリストにサインアップしてくださいhttps//lists.gnu.org/mailman/listinfo/parallel


19
これは質問に答えることも、xargsが同じことを達成できない理由を指摘することもありません。
张]唯2016

8
私にとってxargは、2番目の図が示すとおりに実行するため、反対票を投じてください。
noonex 2017

3
@noonexすべての人が使用しているバージョンのxargsを使用しているわけではなく、-Pがすべてのバージョンのxargsに含まれているわけではないことをご存知ですか?
オレ丹下

20
おそらく、この答えがGNUparallelの作者によって提供されていることをすべての人が知っているわけではありません。
izkeros

1
ほとんどのスクリプトを台無しにするインタラクティブなプロンプトが原因で、最初の試行で説明したように正しく実行されないソフトウェアの明確な広告のために反対票を投じました。
ダニエルソリケッティ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.