timeout
함수 호출로 인해 루프가 중지되는 이유를 알 수 없습니다 . 나는 "해결책"을 갖고 있지만, 이런 일이 어떻게/왜 일어나는지 정말 궁금합니다! cat
명령 시간이 초과되는 것과 관련이 있는 것 같나요 ?
TL;DR
while read -r line; do ... done < file
timeout
에서 a가 발생 하면 종료되어 cat
잘못된 출력 및 종료 코드가 생성됩니다. 루프는~ 아니다파일의 모든 줄을 반복합니다.
대신 파일의 모든 행 중 먼저 배열을 생성한 다음 ...
에서 실행하면 모든 행이 처리되고 종료 코드와 관련된 for line in "${all_lines[@]}"; do
출력이 정확합니다.timeout
스크립트가 grade.sh
모든 내용을 읽고 tests.txt
실행하여 종료 soln.sh
되도록 하려고 한다고 가정합니다 soln.sh
. "작동하는" 예를 보여주기 위해 soln.sh
먼저 sleep
.
tests.txt
first
second
third
fourth
fifth
grade.sh
#!/usr/bin/env bash
while read -r line; do
echo "Test: $line"
output="$(timeout 2 ./soln.sh "$line")"
timed_exit=$?
echo " Soln Output: $output"
echo " Timed exit: $timed_exit"
done < "tests.txt"
soln.sh
#!/usr/bin/env bash
if [[ "$1" == "third" ]]; then
sleep 3
fi
echo "[soln running $1]"
예상 출력
Test: first
Soln Output: [soln running first]
Timed exit: 0
Test: second
Soln Output: [soln running second]
Timed exit: 0
Test: third
Soln Output:
Timed exit: 124
Test: fourth
Soln Output: [soln running fourth]
Timed exit: 0
Test: fifth
Soln Output: [soln running fifth]
Timed exit: 0
soln
영원히 계속되는 작업(입력 대기)을 수행하도록 변경하면 대신 루프가 종료됩니다.
soln.sh
#!/usr/bin/env bash
if [[ "$1" == "third" ]]; then
cat $(find . -name iamnothere.txt) | wc -l
fi
echo "[soln running $1]"
출력이 조기에 종료되고, 추가로 2
, 잘못된 exit
코드가 발생합니다.
Test: first
Soln Output: [soln running first]
Timed exit: 0
Test: second
Soln Output: [soln running second]
Timed exit: 0
Test: third
Soln Output: 2
[soln running third]
Timed exit: 0
Hacky 수정은 먼저 모든 줄을 반복하고 for
이를 우회하는 루프를 사용하는 것입니다.
"결정된"grade.sh
#!/usr/bin/env bash
all_lines=()
idx=0
while read -r line; do
all_lines[idx]="$line"
(( idx++ ))
done < "tests.txt"
for line in "${all_lines[@]}"; do
echo "Test: $line"
output="$(timeout 2 ./soln.sh "$line")"
timed_exit=$?
echo " Soln Output: $output"
echo " Timed exit: $timed_exit"
done
예상 출력
Test: first
Soln Output: [soln running first]
Timed exit: 0
Test: second
Soln Output: [soln running second]
Timed exit: 0
Test: third
Soln Output:
Timed exit: 124
Test: fourth
Soln Output: [soln running fourth]
Timed exit: 0
Test: fifth
Soln Output: [soln running fifth]
Timed exit: 0
이것은 기능입니까, 버그입니까, 아니면 뭔가 빠졌습니까?
스크립트의 나머지 부분이 실행되기 때문에 cat
어떻게든 재정의되는 것 같습니다 .timeout
답변1
cat $(find . -name iamnothere.txt) | wc -l
존재하지 않는다고 가정 iamnothere.txt
하면
cat | wc -l
표준 입력을 소비하며,while
루프가 라인을 읽는 것과 동일한 표준 입력. for
표준 입력을 사용하지 않음으로써 이를 방지합니다 while
. 이는 두 번째 줄의 경우에 베어를 사용하여 관찰할 수 있습니다 cat
. 이는 세 번째 줄이 다음과 같이 읽혀졌음을 보여주기 때문입니다 cat
.
$ cat lines
first
secon
third
$ cat looper
#!/bin/sh
while read line; do
x=$(timeout 2 ./doer "$line")
echo "$line out=$x code=$?"
done < lines
$ cat doer
#!/bin/sh
if [ "$1" = secon ]; then
cat
else
echo "$1 pid$$"
fi
$ ./looper
first out=first pid42079 code=0
secon out=third code=0
$