스크립트에서 백그라운드 프로세스를 시작하고 스크립트가 끝날 때 관리


15

스크립트의 데몬과 비슷한 프로세스를 실행하고 구성하고 싶습니다.
내 쉘은 Cygwin에서 zsh 에뮬레이트되고 데몬은 기본 FTP 서버 인 SFK 입니다.

여기서 중요한 것은 startserv.sh다음과 같이 스크립트를 작성할 수 있습니다.

#!/bin/sh
read -s -p "Enter Password: " pw
user=testuser
share=/fshare
cmd="sfk ftpserv -user=$user -pw=$pw -usedir $share=$share"
$cmd &

스크립트를 실행 한 후 startserv.sh프롬프트가 표시되지 않고 중지됩니다 (종료?).

  • CTRL+ C스크립트와 백그라운드 작업 프로세스를 모두 종료합니다.

  • Enter스크립트하면 백그라운드에서 프로세스 유해를 종료합니다.

어쨌든 난 단지를 통해 볼 수 ps하지 jobs나는 프로세스를 종료하고자 할 때, 그래서, 내가 잔인한 보내야하는 kill -9나는 찬성하지 않으려는 뭔가 신호, CTRL+를 C.

대안 전체 스크립트를 백그라운드에서 실행하는 것입니다. 'Would be'이지만 read스크립트가로 실행되면 명령이 사용자 입력을 가져올 수 없습니다 startserv.sh &.

실제 데몬이 아닌 임시 서버가 필요합니다 . 즉, 스크립트 프로세스가 끝난 후 백그라운드에서 서버 프로세스를 실행하여 간단한 대화 형 쉘 작업 (가상 컴퓨터 게스트 사용)을 수행하고 싶습니다. 쉘에서 살아 남기 위해서는 프로세스가 필요하지 않습니다. 따라서 nohup적절하지 않은 것 같습니다.


를 사용하여 백그라운드에서 실행중인 프로세스의 프로세스 ID를 얻은 bgproc="$!"다음 command "$bgproc" 적절한 조치를 취하십시오. 또한 참조 stackoverflow.com/questions/1908610/...
발렌틴 Bajrami에게

PID 파일을 만들 수도 있습니다. 그런 다음 해당 파일을 읽고 어떤 프로세스 번호인지 확인한 다음 해당 프로세스 번호를 확인하십시오.
jgr208

답변:


18

Enter스크립트하면 백그라운드에서 프로세스 유해를 종료합니다.

거의! 실제로을 누르면 스크립트가 이미 종료되었습니다 Enter. 그러나 이것이 쉘 $PS1을 다시 인쇄하기 때문에 프롬프트를 다시 얻는 방법 입니다.

Ctrl+를 누르는 이유 C는 둘 다 종료되므로 둘이 연결되어 있기 때문입니다. 스크립트를 실행할 때 쉘은 실행할 서브 쉘을 시작합니다. 이 서브 쉘을 종료하면 SIGHUP신호 에서 백그라운드 프로세스가 종료됩니다 .

스크립트, 백그라운드 프로세스 및 서브 쉘을 분리하십시오.

를 사용하면 nohup이 작은 불편 함을 없앨 수 있습니다.

#!/bin/sh
read -s -p "Enter Password: " pw
user=testuser
share=/fshare
cmd="sfk ftpserv -user=$user -pw=$pw -usedir $share=$share"
nohup $cmd &

disown대안

에서 (으) /bin/sh로 전환 할 수 있으면 /bin/bash시도해 볼 수도 disown있습니다. 더 알고, 바로 입력 help disownA의 bash인스턴스입니다.

disown -h $cmd &

백그라운드 프로세스를 훌륭하게 종료

이제 프로세스 종료와 관련 하여를 사용하여 " Ctrl+ C"를 완벽하게 수행 할 수 있습니다 kill. 잔인한 보내지 마십시오 SIGKILL. 대신 다음을 사용할 수 있습니다.

$ kill -2 [PID]
$ kill -15 [PID]

프로세스에 멋진 SIGINT(2) 또는 SIGTERM(15)를 보냅니다 . 프로세스를 시작한 후 PID 값을 인쇄 할 수도 있습니다.

...
nohup $cmd &
echo $!

... 또는 더 나은, A에 대한 스크립트 대기를하게 SIGINT하고, 백그라운드 프로세스로 다시 보내 (이 전경 생각에 스크립트를 유지합니다) :

#!/bin/sh
read -s -p "Enter Password: " pw
user=testuser
share=/fshare
cmd="sfk ftpserv -user=$user -pw=$pw -usedir $share=$share"
nohup $cmd &

# Storing the background process' PID.
bg_pid=$!

# Trapping SIGINTs so we can send them back to $bg_pid.
trap "kill -2 $bg_pid" 2

# In the meantime, wait for $bg_pid to end.
wait $bg_pid

A는 경우 SIGINT충분하지 않습니다, 단지 사용 SIGTERM(15) 대신 :

trap "kill -15 $bg_pid" 2 15

이런 식으로 스크립트 가 백그라운드 프로세스에 대해 SIGINT( Ctrl+ C, kill -2) 또는 a SIGTERM를 수신하면 신호를 스크립트로 wait릴레이합니다. 이러한 신호로 인해 sfk인스턴스가 종료되면wait 종료 호출이 반환되어 스크립트도 종료됩니다. :)


1
+1 매우 유익한 정보입니다. 스크립트가 서브 쉘에서 실행되므로 스크립트에서 스크립트 상위 쉘의 작업 테이블에 액세스 할 가능성이 있습니까? 즉 jobs, 스크립트가 종료 된 후 터미널에서 발행 되는 목록 작업입니다 (대신 ps).
안토니오

1
작업은 현재 쉘과 연관되어 있으며 한 쉘에서 다른 쉘로 전송되지 않습니다. 서브 쉘이 죽으면 작업이 복구되지 않습니다. 백그라운드 프로세스의 PID를 인쇄하면 서브 쉘이 종료 된 후에도 쉽게 정보를 얻을 수 있습니다 ( pid -p).
John WH Smith

좋은 설명이지만 스크립트에 더 많은 명령이 포함되어 있으면 (때문에 wait) 실행되지 않습니다 . 대기를 제거하면 신호 처리가 중단됩니다. /
chefarov
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.