bash 스크립트에서 프로세스를 분리하려면 어떻게해야합니까?


18

스크립트를 종료 할 때 SIGINT가 프로세스로 전달되지 않도록 bash 스크립트에서 프로세스를 분리하려고합니다.

disown터미널에서 직접 명령을 사용 했지만 bash에서는 disownSIGINT가 전달되지 않습니다. 이 스크립트의 목적은 openocd를 시작한 다음 단일 호출로 gdb를 시작하는 것입니다. 스크립트가 종료되지 않으므로 (gdb가 실행 중) SIGINT는 gdb에서 openocd로 계속 전달됩니다. 이는 SIGINT가 gdb에서 정지 명령으로 사용되므로 문제입니다.

터미널에서 다음과 같이 보일 것입니다.

$ openocd &    # run openocd demonized
$ disown $!    # disown last pid
$ gdb          # invoke GDB

이 순서로 터미널에서 호출되면 SIGINT가 gdb에서 openocd로 전달되지 않습니다. 그러나이 동일한 호출이 bash 스크립트에서 발생한 경우 SIGINT가 전달됩니다.

도움을 주시면 감사하겠습니다.

추신 :이 문제는 OS X에 있지만 모든 유닉스 도구에 이식 가능한 도구를 사용하려고합니다.


nohup정답이 아닙니다. 의사 코드 또는 예제 코드를 추가하여 원하는 것을 더 정확하게 표시해야합니다.
Bruce Ediger

1
당신은 같은 도구를 사용할 수 screen있습니까?
Eric Renouf

답변:


17

bash 스크립트에서 프로세스를 분리하려면 다음을 수행하십시오.

nohup ./process &

SIGINT(ctrl + c)로 bash 스크립트를 중지 하거나 쉘이 SIGHUP예를 들어 전송 을 종료 하면 프로세스가 방해받지 않고 정상적으로 계속 실행됩니다. stdout& stderr는 로그 파일로 리디렉션됩니다 : nohup.out.

터미널에서 출력을 볼 수있는 동안 분리 된 명령을 실행하려면 다음을 사용하십시오 tail.

TEMP_LOG_FILE=tmp.log
> "$TEMP_LOG_FILE"
nohup ./process &> "$TEMP_LOG_FILE" & tail -f "$TEMP_LOG_FILE" &

nohupnecassary입니까? 백그라운드에서 명령을 실행하고 터미널을 해제하는 것이 목표 nohup COMMAND &와 다른 점은 무엇입니까 COMMAND &?
James Wierzba

@JamesWierzba 차이점 중 하나는 쉘을 종료 한 후에도 명령을 계속 실행하려면 nohup을 사용하는 것입니다. 웹에는 수천 가지의 광범위한 설명이 있습니다. 예 : stackoverflow.com/questions/15595374/…
marc


4

내가 찾은 해결책에는 Annon Inglorion이 작성한 'detach'라는 프로그램이 있으며 그의 웹 사이트 에서 다운로드 할 수 있습니다

컴파일되면 다음과 같이 스크립트에서 사용할 수 있습니다.

$ ./detach -p debug.pid openocd <args> # detach openocd
$ gdb <args>                           # run gdb
$ kill -9 $(cat debug.pid)             # end openocd process
$ rm debug.pid                         # remove file containing process id

이 첫 번째 행은 새 프로세스 (openocd 실행)를 작성하고 나중에 사용하기 위해 프로세스 ID를 파일 (debug.pid)에 저장합니다. 이것은 Oliver의 답변에 제공된 것처럼 pid를 grepping하는 문제를 방지합니다. 다음 차단 프로그램 (gdb)을 종료하면 pid를 저장하는 파일이 분리 된 프로세스를 직접 종료하는 데 사용됩니다.


확인하고 detach놀라운 일 을합니다.
AS

2

간단하고 휴대용 솔루션 :

echo "openocd" | at now #openocd starts now, but via the at daemon, not the current shell!
pid=$(ps -ef | grep "[o]penocd" | awk '{print $1}')  
echo "openocd is running with pid: $pid"
gdb

일부 이식성 경고 : ps옵션은 OS에 따라 다릅니다! 대신 다음과 같은 변형을 사용할 수 있습니다 { ps -ef || ps aux ;} | grep '[o]penocd | cut -f 1. at사용할 수 없었습니다 (이상하지만 이런 일이 발생합니다 ...). $(...)상당히 오래된 쉘이 필요하지 않으면 백틱을 사용하십시오.


하나 이상의 프로세스가 같은 이름으로 실행 중이거나 다른 프로세스에 openocd라는 단어가 포함되어 있으면 pid를 grepping하면 예기치 않은 일이 발생할 수 있습니다.
오리온

1
@ orion : 아이디어를 제시하는 간단한 예를 들었습니다. 언급 한 우려 사항은 쉽게 제거 할 수 있습니다 : at프로그램을 시작하고 파일에서 대신 pid를주는 스크립트를 시작하고 주 스크립트가 대기하도록하십시오. 파일을 표시 한 다음 pid를 읽습니다.
Olivier Dulac

물론 (너무 단순한) 예제에서 grep을 awk 내부의 오른쪽 열 (일반적으로 $ 8)로 테스트해야합니다 (컬럼은 운영 체제 및 버전 / ps 옵션에 따라 다름)
Olivier Dulac
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.