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 명령줄에 지정된 입력 파일을 읽고 런타임에 해당 파일을 사용한다는 것을 의미합니다. 실행 중에 파일을 수정할 수 없으며 수정된 입력이 실행에 반영될 수 없습니다.
셋 또는 넷