2分以内に端末に何も出力されない場合は、Pythonスクリプトを終了したいと思います。

2分以内に端末に何も出力されない場合は、Pythonスクリプトを終了したいと思います。

これは私の現在のbashです。ただループです。

while true ; do 
     python3 /Users/Name/Desktop/pythoncode.py
done

pythoncode.py2分以内に端末に何も出力されない場合は終了したいです。

答え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)

注:この例では、行ベースの出力(または文字単位の出力)を想定していますreadprintf


この構造とパイプの使用の違いは、ここにコマンドがあることです。コマンドが終了すると、ファイル記述子からのファイル入力が終了し、サブシェルの対応する記述子に書き込むコマンドも終了します。だから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。

関連情報