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)

참고: 이 예에서는 줄 기반 출력(또는 문자별 출력)을 가정합니다 read.printf


이 구조와 파이프 사용의 차이점은 여기에 명령이 있다는 것입니다. 명령이 종료되면 파일 설명자로부터의 파일 입력이 종료되고 하위 쉘의 해당 설명자에 쓰는 명령도 종료됩니다. 그래서 Python 스크립트가 종료되었습니다.시간 초과 후.

다음과 같이 배관할 때:

python3 script.py | { 
    while IFS= read -r -t120 x; do
        printf "%s\n" "$x"
    done
}

두 개의 명령을 실행하고 두 번째 명령이 종료되면(시간 초과로 인해) 첫 번째 명령은 파이프에 쓰기를 다시 시도할 때까지 계속 실행됩니다. 이런 일이 발생하면 손상된 파이프로 인해 종료되고 아무 것도 다시 기록되지 않습니다. 그래서 여기서 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.

관련 정보