Xargs

我可以在 xargs 已經執行時將行附加到 xargs 的輸入文件嗎?

  • March 12, 2021

我正在使用 xargs 工具來管理串列和並行執行的多個命令,即同時執行 4 個任務,同時使用 -a 命令行選項從要執行的命令列表中讀取,即

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

其中 files.txt 包含配置列表,該列表作為命令行參數傳遞給 runSh.sh。

我的問題是,我可以在 xargs 執行時將行附加到 files.txt,並且 xargs 會將這些附加命令添加到它的執行隊列中,還是它只在執行時讀取 files.txt 輸入文件一次?

謝謝

您可以在下面執行它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,它什麼都不返回,這意味著end-of-file,之後它不再讀取。

因此,xargsxargs這裡-P-dGNU 是 GNU 特定的)只會讀取附加數據,前提是它在xargs啟動最後一個命令之前已附加。

如果您希望始終能夠添加更多數據並確保xargs讀取它,您可以將其更改為:

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

(假設 shell 支持程序替換,例如 ksh、zsh 或 bash)

這一次,xargs將從永遠不會結束的管道中讀取(永遠不會看到文件結尾)。tail -f,因此xargs將永遠等待來自該文件的更多數據。

引用自:https://unix.stackexchange.com/questions/638964