Linux에서 일시 중단 상태로 프로세스를 시작하려면 어떻게합니까?


19

실제로 Ctrl+Z시작한 직후에 누르는 것처럼 동작하는 프로세스가 필요합니다 .

바라건대, 쉘 스크립트를 사용하여 그러한 작업을 수행하는 것이 가능합니다.

또한 결과 PID를 아는 것이 좋으므로 나중에 프로세스를 계속할 수 있습니다.

답변:


7

프로세스를 시작한 후 SIGSTOP으로 보내 일시 중지 할 수 있습니다. 다시 시작하려면 SIGCONT를 보내십시오. 이 작은 스크립트가 도움이 될 것 같아요

#!/bin/bash
$@ &
PID=$!
kill -STOP $PID
echo $PID
wait $PID

프로세스를 실행하고 (명령으로 매개 변수로 전송) 일시 중단하고 프로세스 ID를 인쇄 한 후 종료 될 때까지 기다립니다.


1
내가 마지막에 계속 그것을 수정 : [입력] #!/bin/bash [ENTER] $@ & [ENTER] PID=$! [ENTER] kill -STOP $PID [ENTER] echo "Suspended: $PID, press ENTER to continue it" [ENTER] read [ENTER] kill -CONT $PID [ENTER] wait $PID [입력]echo
java.is.for.desktop

7
아시다시피, 서브 프로세스가 STOP 신호를 보내기 전에 서브 프로세스가 완료 될 수 있습니다.
MikeyB

16
경주에서 또 다른 하루.
ctrl-alt-delor

23

어떤 환경에서 프로세스를 작성하고 있습니까?

C 코드와 같은 환경에서이 작업을 수행하는 경우 fork ()를 수행 한 다음 자식에서 exec () 전에 SIGSTOP을 자신에게 보내서 추가 실행을 방지 할 수 있습니다.

보다 일반적인 해결책 (아마도 최선)은 그렇게하는 스텁을 만드는 것입니다. 따라서 스텁 프로그램은 다음을 수행합니다.

  • 실제 프로그램의 이름과 인수로 구성된 인수를 취하십시오.
  • SIGSTOP을 보내다
  • exec () 적절한 인자를 가진 실제 프로그램

이렇게하면 신호를 보내기 전에 새 처리가 너무 멀어지면서 어떤 종류의 경쟁 조건을 피할 수 있습니다.


쉘의 예 :

#!/bin/bash
kill -STOP $$
exec "$@"

그리고 위의 코드를 사용하여 :

michael@challenger:~$ ./stopcall.sh ls -al stopcall.sh

[1]+  Stopped                 ./stopcall.sh ls -al stopcall.sh
michael@challenger:~$ jobs -l
[1]+ 23143 Stopped (signal)        ./stopcall.sh ls -al stopcall.sh
michael@challenger:~$ kill -CONT 23143; sleep 1
-rwxr-xr-x 1 michael users 36 2011-07-24 22:48 stopcall.sh
[1]+  Done                    ./stopcall.sh ls -al stopcall.sh
michael@challenger:~$ 

jobs -lPID를 보여줍니다. 그러나 쉘에서 수행하는 경우 PID가 직접 필요하지 않습니다. 당신은 할 수 있습니다 : kill -CONT %1(당신은 하나의 직업 만 가정).

둘 이상의 직업으로 하는가? 독자를위한 연습으로 남겨두기 :)


나는 쉘 스크립트에서 이것을하기를 바랐다.
java.is.for.desktop

셸 스크립트에서이 작업을 수행하려면 스텁 프로그램을 사용하십시오.
MikeyB

20

MikeyB의 답변이 맞습니다. 에서 이 질문에 수퍼 유저에 대한, 여기에 더의 간결한 버전입니다 :

( kill -SIGSTOP $BASHPID; exec my_command ) &

이를 이해하려면 유닉스에서 프로세스가 시작되는 방식을 이해해야합니다. exec시스템 호출 기존 PID를 유지하면서 현재 실행중인 프로그램을 새로운 프로그램으로 대체합니다 . 길도록 만들어 독립된 프로세스 제이다 fork하고 exec원하는 프로그램 자식 프로세스에서 실행되는 프로그램을 대체.

이 셸 명령의 구성 요소는 다음과 같습니다.

  1. 괄호 (...)는 서브 쉘 (BASH의 다른 인스턴스)을 시작합니다.
  2. kill명령은 STOP 신호를이 프로세스로 전송하여 일시 중단 상태로 만듭니다.
  3. 프로세스가 CONT신호 를 보내어 프로세스를 계속하자마자 exec명령 을 통해 원하는 프로그램 으로 대체됩니다 . my_command하위 쉘의 원래 PID를 유지합니다.
  4. $!변수를 사용 하여 프로세스의 PID를 얻을 수 있습니다 .

2
나는 기본적으로 정확하기 때문에 이것을 좋아합니다 (단지 -s STOP대신 사용해야 합니다 -SIGSTOP). 아직도 궁금합니다. 왜 $BASHPID대신에 있어야 $$합니까? (차이를 이해하지 못할 수도 있습니다).
Hibou57

1
들면 $$VS $BASHPID, I는 동안 이전되지 후자 서브 쉘의 PID 나 확인. bash는 스크립트에서 팁을 적용, 가장 자주 실패하고이 같은 뭔가를해야 :이 재미있는 문제는 PID=$!; ps -p $PID; kill -s CONT $PID;... 내가 제거하면 실패 ps -p $PID부분 (? 사망) 프로세스가 오류 메시지가 어디없이 사라 보인다 . 대화식 쉘에서는 문제가 없으며 스크립트에서만 발생합니다. 너무 신비 롭습니다.
Hibou57

my_command의 파일 디스크립터를 나열하기 위해이 솔루션을 사용하려고했습니다. ( goo.gl/cNbUE8 ) 그러나 설명자는 여전히 my_command와 동일하지 않습니다.
rasty.g

$BASHPIDbash 이외의 쉘 을 대체 하는 옵션에 대해서는 여기를
Jakob
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.