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そのファイルからより多くのデータが表示されるまで永遠に待ちます。

おすすめ記事