SIGTERM을 완전히 무시하는 게임 서버 프로그램(SRCDS)을 실행하고 있습니다. 서버를 완전히 종료하는 유일한 방법은 대화형으로 "quit"를 입력하는 것입니다.
SIGTERM을 포착하고 프로그램의 STDIN으로 "종료"를 보내는 bash 스크립트로 이 프로그램을 래핑할 수 있는 방법이 있습니까? 그렇지 않으면 일반 작업에서 래퍼는 STDIN 및 STDOUT이 전혀 존재하지 않는 것처럼 전달해야 합니다.
내가 달성하려는 목표에 대한 다이어그램:
일반 외과:
--- STDIN ---> | | --- STDIN ---> | |
| Bash Script | | Server Program |
<-- STDOUT --- | | <-- STDOUT --- | |
SIGTERM은 다음을 보냅니다:
"quit"
--- STDIN ---> | | --- STDIN ---> | |
-- SIGTERM --> | Bash Script | | Server Program |
<-- STDOUT --- | | <-- STDOUT --- | |
답변1
프로그램이 터미널에서 실행될 것으로 예상되는지 여부에 따라 다릅니다. 그렇다면 이 작업을 수행할 수 없을 것 같습니다 bash
. 비슷한 것을 사용해야 합니다 expect
. 예:
래퍼.예상:
puts "<<< pid=[pid] >>>"
spawn {*}$argv
trap {send "quit\n"} SIGTERM
interact
BC를 예로 들어보겠습니다.
expect wrapper.expect bc -q
<<< pid=4771 >>>
spawn bc -q
kill 4771
다른 창에서 A를 사용하면 행이 expect
로 전송 됩니다 . 이는 하위 프로세스의 pid 가 아니라 프로세스의 pid입니다.quit
bc
4771
expect
bc
또 다른 옵션은 ioctl을 사용하여 TIOCSTI
현재 터미널에 라인을 삽입하는 것입니다. quit
그러나 이 작업은 쉘에서 수행할 수 없으며 여전히 작은 C(또는 Perl, Python 등) 프로그램이 필요합니다. 호출합니다 ioctl()
( TIOCSTI
이미 OpenBSD에서는 시스템에서 삭제됩니다).
답변2
이 시도:
#!/bin/bash
coproc cat -n # replace 'cat -n' with actual server program to be launched
# first some necessary file-descriptors fiddling
exec {srv_input}>&${COPROC[1]}-
exec {srv_output}<&${COPROC[0]}-
# background commands to relay normal stdin/stdout activity
cat <&0 >&${srv_input} &
cat <&${srv_output} >&1 &
# set signal handler up
term_received=false ; trap 'term_received=true' SIGTERM
# endless loop waiting for events
while true; do
# wait for server to exit or sigterm received
wait ${COPROC_PID}
exit_status=$?
# if sigterm received:
if [ $exit_status -gt 128 ] && $term_received ; then
# kill proxy command relaying stdin to server
kill %2
# send quit to server's stdin
echo $'\n'quit >&${srv_input}
# close server's stdin
exec {srv_input}<&-
# wait for actual server to exit
wait ${COPROC_PID}
exit $?
# something else happened: kill proxy commands and exit with server's own exit status
else
kill %2
kill %3
fi
exit $exit_status
done
이 스크립트가 귀하의 질문에 답변하면 더 완전한 설명을 추가하겠습니다.