これは私の現在のbashです。ただループです。
while true ; do
python3 /Users/Name/Desktop/pythoncode.py
done
pythoncode.py
2分以内に端末に何も出力されない場合は終了したいです。
答え1
そしてzsh
:
zmodload zsh/system
(
echo $sysparam[pid]
exec python3 /Users/Name/Desktop/pythoncode.py
) | {
read pid
if sysread -o 1 -s 1 -t120; then
cat
else
kill -s PIPE $pid 2> /dev/null
fi
}
を使用すると、bash
次のことができます。
(
echo "$BASHPID"
exec python3 /Users/Name/Desktop/pythoncode.py
) | {
read pid
if LC_ALL=C IFS= read -rd '' -n1 -t120 byte; then
if [ -n "$byte" ]; then
printf %s "$byte"
else
printf '\0'
fi
cat
else
kill -s PIPE "$pid" 2> /dev/null
fi
}
これにより、スクリプトが端末ではなく標準出力に書き込むかどうかを確認します。
コマンドが何かを書いたときに停止し、2分間何も出力しない場合、つまり2分間アクティビティがないとコマンドを終了する場合は、次のことができますsocat
。
socat -T120 'exec:python3 /Users/Name/Desktop/pythoncode.py' -
または以下を使用してzsh
:
zmodload zsh/system
(
echo $sysparam[pid]
exec python3 /Users/Name/Desktop/pythoncode.py
) | {
read pid
while
sysread -o 1 -t 120; ret=$?
(( ret == 0 ))
do continue; done
# 5 means EOF
(( ret == 5 )) || kill $pid
}
答え2
を使用すると、プロセスのbash
オーバーライドとリダイレクト、タイムアウトwhile
のあるループも使用できますread
-t
。タイムアウトによってループが終了した場合while
(Pythonスクリプトに出力がなく、2分間無効になっているように見える場合)、サブシェルはもう存在しません。
while IFS= read -r -t120 x; do
printf "%s\n" "$x"
done < <(python3 script.py)
注:この例では、行ベースの出力(または文字単位の出力)を想定していますread
。printf
この構造とパイプの使用の違いは、ここにコマンドがあることです。コマンドが終了すると、ファイル記述子からのファイル入力が終了し、サブシェルの対応する記述子に書き込むコマンドも終了します。だからPythonスクリプトは終了しました。タイムアウト後。
次のように配管するとき:
python3 script.py | {
while IFS= read -r -t120 x; do
printf "%s\n" "$x"
done
}
2つのコマンドを実行し、2番目のコマンドが終了すると(タイムアウトのため)、最初のコマンドはパイプへの書き込みを再試行するまで実行され続けます。これが発生すると、破損したパイプのために終了し、何も書き戻されません。だからここでPythonスクリプトが終了しました。タイムアウト後に書き直すとき。
答え3
許容精度が約1秒の場合は、それを使用date +%s
して実際の時間を収集し、スクリプトに出力がない時間を確認できます(シェル変数として収集)。
ELAPSED_T=0 # the time that has passed since last output
LAST_OUT_T=`date +%s` # avoid to stop if the first iteration has empty output
while [ "$ELAPSED_T" -lt 120 ]; do # continue if the last output was printed less than 120 seconds ago
OUT=`python3 /Users/Name/Desktop/pythoncode.py` # run the script and collect the output
echo "$OUT" # print the output on screen
if [ -n "$OUT" ]; then # if the output is not empty, update the last output time
LAST_OUT_T=`date +%s`
else # otherwise, evaluate how much time has passed since last output
NOW_T=`date +%s`
ELAPSED_T=$((NOW_T - LAST_OUT_T))
fi
done
答え4
GNUコマンドを確認したい場合がありますtimeout
。期間を引数として使用し、その後にコマンドが続きます。これは簡単な呼び出しです:
timeout 5s ping www.website.com
マンページから:
TIMEOUT(1) User Commands TIMEOUT(1)
NAME
timeout - run a command with a time limit
SYNOPSIS
timeout [OPTION] DURATION COMMAND [ARG]...
timeout [OPTION]
DESCRIPTION
Start COMMAND, and kill it if still running after DURATION.
...
タイムアウトが終了したら、プロセスに送信される信号の種類(HUP、9、SIGTERMなど)を指定することもできます。
HTH。