Bash의 timeout 명령

Faaiq Bilal 2024년2월15일
  1. Bash의 timeout 명령
  2. Bash에서 SIGKILL 신호와 함께 timeout 사용
Bash의 timeout 명령

이 기사는 Bash에서 GNU의 coreutils 패키지에 있는 timeout 명령을 사용하여 특정 프로그램에 대한 시간 제한을 설정하는 방법을 쉽게 안내합니다.

Bash의 timeout 명령

서버에서 데이터를 가져오거나 임의의 입력으로 함수 또는 프로그램을 실행하는 것과 같은 많은 상황에서 프로그램 또는 함수는 매우 오랜 시간 동안 또는 무기한 실행될 수 있습니다.

이러한 경우 프로그램을 중지하고 더 많은 시간과 자원을 낭비하지 않도록 방지하는 것이 필수적입니다.

여기에서 타임아웃 기능이 등장합니다. 사용자가 시간 제한을 정의한 다음 성공적으로 완료될 때까지 프로그램을 실행할 수 있으며 사용자 정의 시간 제한까지 너무 오래 걸리면 프로그램이 종료됩니다.

시간 초과 기능은 일반적으로 대부분의 프로그래밍 언어에 내장되어 있습니다. 그러나 Bash의 경우 내장되어 있지 않으며 coreutils라는 외부 패키지의 일부입니다.

이 패키지는 GNU에서 개발 및 유지 관리하며 많은 기본 유틸리티의 구현을 포함합니다.

coreutils 패키지는 LINUX 시스템에서 sudo apt-get install -y coreutils 명령을 실행하여 간단하게 설치할 수 있습니다.

macOS 시스템에서 coreutils를 가져오려면 먼저 Homebrew를 설치해야 합니다. Homebrew를 얻으려면 명령 터미널에서 아래 명령을 실행하십시오.

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Homebrew 설치가 완료되면 아래 명령어를 실행합니다.

brew install coreutils
Note
macOS에서 coreutils 명령의 경우 모든 명령에는 이름 앞에 g 접두사가 붙습니다(예: gdir 또는 gtimeout).

coreutils 패키지가 설치되어 있으면 timeout 기능을 사용할 수 있습니다. 예를 들면 다음과 같습니다.

timeout 10 ping google.com

위의 명령은 다음을 출력합니다.

시간 제한 명령 사용

Bash의 ping 유틸리티는 내장되어 있으며 수동으로 중단될 때까지 계속 실행됩니다. 기본적으로 ping은 1초마다 패키지를 전송합니다.

위와 같이 timeout 명령은 timeout 명령 바로 다음의 숫자가 시간 제한이므로 10초 후에 ping을 죽입니다.

따라서 timeout 10 cmd1 명령은 cmd1이 성공적인 완료 또는 10초 중 더 빠른 시간까지 실행됨을 의미합니다. timeout 명령의 시간 단위는 초입니다.

분, 시간 또는 일 단위로 측정된 시간 값을 사용하려면 각각 m, h 또는 d를 추가합니다.

예를 들어 제한 시간을 2분으로 설정하려면 다음과 같이 하십시오.

timeout 2m programToRun

프로세스가 시간 초과되면 시간 초과의 종료 상태는 124입니다. 다음 예에서는 이를 사용하여 프로세스가 시간 초과되었는지 여부를 확인합니다.

timeout 1 ping 8.8.8.8 -w3
EXIT_STATUS=$?
if [ $EXIT_STATUS -eq 124 ]
then
echo 'Process timed out!'
else
echo 'Process did not timeout.'
fi
exit $EXIT_STATUS

위 그림의 예에서 프로세스가 1초 내에 완료되지 않으면 프로세스가 시간 초과됩니다. -w3 확장자는 주소가 세 번 ping됨을 나타냅니다.

따라서 이 프로세스는 항상 시간 초과되어 다음 출력을 제공합니다.

PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=57 time=40.4 ms
Process timed out!

모든 내부 시간 초과는 동일한 종료 상태(124)를 초래한다는 점에 유의해야 합니다. 따라서 이 출력은 지정된 시간 제한을 사용하여 프로세스가 시간 초과되었거나 일부 내부 시간 초과로 인해 프로세스가 종료되었음을 나타냅니다.

Bash에서 SIGKILL 신호와 함께 timeout 사용

일반적으로 timeout 기능은 SIGTERM 신호를 보내 시간 제한에 도달하면 프로그램 실행을 중지합니다. 문제는 일부 프로그램이 SIGTERM 신호를 무시하고 계속 실행될 수 있다는 것입니다.

이것은 SIGKILL 신호가 들어오는 곳입니다. 프로세스 및 모든 자식 프로세스의 실행을 즉시 중지하며 차단하거나 무시할 수 없습니다. SIGKILL과 함께 타임아웃을 사용하려면 -s 플래그를 추가해야 합니다.

예를 들어:

timeout -s SIGKILL 10 programToRun

스크립트에서 실행할 때와 같이 셸에서 직접 timeout을 실행하지 않는 경우 timeout 명령에 --foreground를 추가하는 것이 중요합니다.

timeout 명령에 대한 많은 대안을 사용할 수 있으며, 모두 주로 sleep과 함께 일부 종료 신호를 사용한 다음 sleep이 종료되는 즉시 중지되는 필수 명령 또는 프로그램을 실행하는 동일한 논리를 기반으로 합니다.

예:

(sleep 2 && killall prog) & ./prog

위의 코드는 prog가 실행을 완료하지 않은 경우 2초 후에 prog의 모든 프로세스를 종료합니다. 이러한 솔루션은 작동할 수 있지만 timeout 명령만큼 안전하고 신뢰할 수는 없으므로 항상 timeout을 대신 사용하는 것이 좋습니다.