複数のフォルダに対して連続的にコマンドを実行する

複数のフォルダに対して連続的にコマンドを実行する

親フォルダ「parent」があります。このフォルダにはサブフォルダと「names.txt」というファイルがあります。ファイルには、次のサブフォルダーの名前が含まれています。

Parent_folder
folder1
folder2
folder3
folder4
.
.
.
.
names.txt

"names.txt"ファイルの内容は次のとおりです。

folder1
folder2
folder3
folder4
.
.
.

各フォルダには画像があり、各画像に10個のスクリプトを連続して適用したいと思います。各スクリプトは各フォルダで適切な操作を実行してから2番目のスクリプトを実行する必要があります。These scripts have different names and they are exist in one folder. I set an environment by sourcing a file then I can call these scripts by its name from terminalまた、このプロセスをすべてのフォルダに一度に適用したいと思います。つまり、スクリプト#1を実行すると、すべてのフォルダで同時に実行したいと思います。完了すると、スクリプト#2が起動します。すべてのフォルダなどですぐに起動したいです。これを達成するために、次のコードを書きました。

#!/bin/bash
path=PATH/TO/THE/PARENT/FOLDER
for i in $(cat $path/names.txt); do
{
script#1
} &
{
script#2
} &
.
.
.

done

このコードは、すべてのコマンドが同時に実行されるため、効率的には実行されません。コマンドをすべてのフォルダで同時に継続的に実行したいと思います。私は何が間違っていましたか?

ベストアンサー1

まず、最初の(唯一の)コマンドライン引数で指定されたディレクトリに変更し、必要なすべての設定/変数の初期化などを実行し、必要な引数を使用して10個のスクリプトを実行するラッパースクリプトを作成します。

たとえば、各スクリプトがディレクトリ内のすべての.jpg、.png、および.gifファイルを処理する場合:

#! /bin/bash
# example-wrapper.sh

cd "$1"

script1 *.{jpg,png,gif}
script2 *.{jpg,png,gif}
script3 *.{jpg,png,gif}
script4 *.{jpg,png,gif}
script5 *.{jpg,png,gif}
script6 *.{jpg,png,gif}
script7 *.{jpg,png,gif}
script8 *.{jpg,png,gif}
script9 *.{jpg,png,gif}
script10 *.{jpg,png,gif}

次にfind、ディレクトリの一覧をparallel

find /path/to/parent/ -mindepth 1 -type -d -print0 | 
  parallel -0 -n 1 ./example-wrapper.sh

-mindepth 1のオプションにはfind最上位ディレクトリ、つまり親ディレクトリ自体は含まれません。)

./example-wrapper.shデフォルトでは、並列処理は、保持している各CPUコアに対して1つのインスタンス(1つの「ジョブ」)を実行します。各インスタンスには()ディレクトリ名があります-n 1。あるジョブが完了すると、別のジョブが開始されます(実行するジョブが残っている場合)。

これにより、ジョブが CPU 時間をかけて互いに競合することなく、使用可能な CPU パフォーマンスの使用を最大化します。

一度に実行されるジョブの数を調整するparallelために使用できるオプション。-jCPU 集約型タスクの場合は、システム コアごとに 1 つのタスクというデフォルト設定が必要な場合があります。

ジョブがCPU集約的ではなく、I / Oバインディングがより傾向にある場合は、入力ファイルのサイズと保存速度に応じて、各コアに対して2〜3個のジョブを実行する必要があります。対応するストレージを構成するデバイスのタイプ - たとえば、SSD は検索待ち時間の影響を受けないため、ディスク全体でデータを検索する複数のプロセスによってハードドライブの速度が遅くなり、検索時間が遅くなります。ランダム - Linuxのディスクバッファリング/キャッシュは役立ちますが、問題は排除されません。

これらのタスクの実行中に他のタスクを実行するには(たとえば、一般的なデスクトップを使用する)、システムより1〜2個のコアを使用するように指示する-jタスク(8コアシステムなど)を使用します。parallel-j 6

注:並列プロセスを調整するのは芸術であり、最良の結果を得るにはいくつかの実験が必要です。

とにかく、ソースman parallel

--jobs N、、、、 -j N--max-procs N-P N

役職数。最大N個のジョブを並列に実行します。 0 はできるだけ多くを意味します。デフォルトは100%で、これはCPUコアごとに1つのタスクを意味します。

--semaphoreデフォルト値が1に設定されると、ミューテックスが生成されます。

これは実際には基本的で元の使い方ですparallel。より多くのことができます。詳しくはマニュアルページをご覧ください。

ところで、ジョブを並列に実行するオプションxargsもあります。-Pこのように簡単な使い方でxargs -Pは or を使ってもあまり違いはありませんparallel。しかし、要件がより複雑な場合parallel

parallelほとんどのLinuxディストリビューション用にパッケージ化されている必要があります。そうでない場合は、以下で利用できます。https://www.gnu.org/software/parallel/

おすすめ記事