
timeout
関数呼び出しによってループが停止する理由はわかりません。 「解決策」がありますが、どうして/なぜこんなことが起こるのか本当に気になります!これはcat
コマンドタイムアウトに関連しているようです。
長い話を短く
while read -r line; do ... done < file
timeout
が発生すると終了し、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]"
早期終了、extra 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
ハッキー修正は、まず各行を繰り返し、次にループを使用して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
。これは、2行目のbareを使用して観察できますcat
。これは、3行目を読んだことを示します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
$