내 PID 목록에서 PID가 제거되지 않는 이유를 설명할 수 있는 사람이 있나요? 이 루프에 들어갈 때마다 for 루프는 여전히 같은 횟수로 발생합니다. var i는 pid 수와 같습니다. 따라서 모든 pid가 완료되면 while 루프가 중지되어야 하지만 그렇지 않습니다! 여전히 pids 배열에 pid가 있습니다.
이 명령은 작동하지 않는 것 같습니다: pids=("${pids[@]/$pid}") 뭔가 문제가 있습니까? pids 배열에서 $pid를 제거하고 싶습니다.
while [ $i != 0 ]
do
for pid in "${pids[@]}"
do
if [ -z "$(ps -p $pid -o pid=)" ]
then
echo "i = $i ,pid $pid is finished" | tee -a $LOGFILE
((i--))
pids=("${pids[@]/$pid}")
echo
else
echo "i = $i ,pid $pid is not finished"
fi
done
sleep 4
clear
done
답변1
문제는 이렇게 하면 배열의 항목이 빈 문자열("")로 대체된다는 것 ("${pids[@]/$pid}")
입니다 . $pid
따라서 이 프로젝트는 실제로는삭제됨배열에서 그것은 단지교체됨빈 문자열 항목이 있습니다.
나는 일부 pid가 배열에서 "제거"된 후 다음 사이클에서 for pid in "${pids[@]}"
다음 줄이 오류를 생성할 것이라고 추측합니다.일부$pid 변수는 비어 있습니다.
if [ -z "$(ps -p $pid -o pid=)" ]
이로 인해 ps
stderr에 일부 오류가 발생할 수 있지만 명령(STDOUT)의 출력은 비어 있으므로 $i
1 씩 감소하여 $i
결국 0 아래로 떨어질 수 있으며 결코 0이 되지 않으므로 루프가 멈추지 않습니다.
배열의 모든 항목은 숫자이므로 다음 줄에서 따옴표를 제거하여 이 문제를 해결할 수 있습니다.
pids=("${pids[@]/$pid}")
따라서 다음과 같습니다.
pids=(${pids[@]/$pid})
따옴표가 없으면 빈 요소가 배열에서 제거됩니다.
다음은 간단한 예입니다.
$ array=( 1 2 3 )
$ echo "${array[@]/1}"
2 3
# Notice that the first item is replaced with an empty string
$ echo ${array[@]/1}
2 3
# Without the quotes, the empty string is removed
이는 배열의 항목이 숫자이기 때문에 작동한다는 점에 유의하세요. 배열에 문자열과 공백이 포함되어 있으면 작동하지 않습니다.
또한 이 방법은하위 문자열(반드시 전체 배열 항목일 필요는 없음), 예를 들어 , pids=( "1", "123" )
및 의 경우 pid=1
결과 (${pids[@]/1})
는 ( "23" )
"123"에서 "1"을 제거하고 "23"만 남깁니다.
아래를 봐주세요답변배열의 내용에 관계없이 모든 배열에서 항목을 제거하는 방법과 자세한 내용을 알아보세요.
부인 성명:
이 답변은 스크립트가 예상대로 작동하지 않는 이유만 설명합니다. 내 제안으로 인해 스크립트가 작동할 수는 있지만 가장 최적화된 방식으로 작성되지는 않았습니다. 스크립트를 더 깔끔하고 효율적으로 만들 수 있는 많은 변경 사항이 있지만 이 답변에서는 이에 대해 다루지 않겠습니다.