xargsがすでに実行されているときにxargsの入力ファイルに行を追加できますか?

xargsがすでに実行されているときにxargsの入力ファイルに行を追加できますか?

私はxargsツールを使って複数のコマンドをシリアルで並列に実行することを管理しています。つまり、-aコマンドラインオプションを使用して実行するコマンドのリストを読み取っている間、4つのタスクを同時に実行しています。

xargs -t -P 4 -L 1 -I '%' -a files.txt runSh.sh

ここで files.txt には、コマンドライン引数として runSh.sh に渡される構成のリストが含まれています。

私の質問は、xargsが実行されている間にfiles.txtに行を追加でき、xargsがこれらの追加されたコマンドを実行キューに追加できますか、それとも実行中にfiles.txt入力ファイルを一度だけ読みますか?

ありがとう

答え1

これを実行して、strace何が起こっているのかを確認できます。

$ seq 10 > files.txt
$ strace -tt -e read xargs -t -P 4 -n1 -d'\n' -a files.txt sleep
[...]
18:19:32.907311 read(3, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n", 512) = 21
sleep 1
18:19:32.908129 read(4, "", 4)          = 0
sleep 2
18:19:32.908830 read(4, "", 4)          = 0
sleep 3
18:19:32.909406 read(4, "", 4)          = 0
sleep 4
18:19:32.909977 read(4, "", 4)          = 0
18:19:33.912774 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=453051, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
sleep 5
18:19:33.914702 read(4, "", 4)          = 0
18:19:34.910440 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=453052, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
sleep 6
18:19:34.911021 read(4, "", 4)          = 0
18:19:35.911315 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=453053, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
sleep 7
18:19:35.912257 read(4, "", 4)          = 0
18:19:36.912158 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=453054, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
sleep 8
18:19:36.912623 read(4, "", 4)          = 0
18:19:38.916348 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=453176, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
sleep 9
18:19:38.917196 read(4, "", 4)          = 0
18:19:40.913135 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=453177, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
sleep 10
18:19:40.914137 read(4, "", 4)          = 0
18:19:40.914808 read(3, "", 512)        = 0
18:19:42.914324 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=453178, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
18:19:44.914685 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=453179, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
18:19:47.919202 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=453272, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
18:19:50.916332 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=453273, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
18:19:50.917068 +++ exited with 0 +++

ご覧のとおり、最初は最大512バイトのデータを読み取ります。私の場合、ファイルの内容全体(21バイト)を読み、4つのプロセスを開始するのに十分でした。

最初のコマンドsleepが返されると、次のコマンドが開始されます。

最初に読み取ったすべてのコマンドを起動すると、read()そのファイル記述子3から何も返されません。ファイルの終わり、もう読みません。

したがってxargs(ここではGNU xargs-PすべてGNU関連)は、-d最後のコマンドが実行される前に追加された追加データのみを読み取ります。xargs

常により多くのデータを追加して確実に読み取れるようにするには、xargs次のように変更できます。

xargs -t -P 4 -n1 -d'\n' -a <(tail -fn +1 files.txt) sleep

(シェルがksh、zsh、bashなどのプロセス置換をサポートしていると仮定)

今回はxargs終了しないパイプから読み込みます(ファイルの終わりは表示されません)。tail -fしたがって、xargsそのファイルからより多くのデータが表示されるまで永遠に待ちます。

答え2

今実験しました。私は次のような小さなシェルスクリプトを作成しました。

echo $1
sleep 1m

以下の設定ファイルがあります。

one
two
three
four

その後、コマンドを開始しました。

xargs -t -P 4 -L 1 -a input_lines.txt ./run2.sh

実行後、input_lines.txtファイルを次のように修正しました。

one
two
three
four
five

実行が完了し、出力のみになります。

./run2.sh one
./run2.sh two
one
./run2.sh three
two
./run2.sh four
three
four

まとめると、これはxargsが-aコマンドラインで指定された入力ファイルを読み取り、実行時にそのファイルを使用することを意味します。実行中にファイルを変更できず、変更された入力を実行に反映できません。

セットまたはネット

関連情報