백그라운드에서 Python 스크립트를 실행한 후 대화형 Python 셸 열기

백그라운드에서 Python 스크립트를 실행한 후 대화형 Python 셸 열기

python3 -i test.pytest.py를 실행한 후 대화형 Python 셸을 엽니다. 그러나 백그라운드에서 실행하려고 하면 python3 -i test.py & 작업이 자동으로 중지 ^C되고

[4]+  Stopped                 python3 -i test.py

, 그 후에는 Python의 대화형 셸에 액세스할 수 없습니다(test.py의 변수는 여전히 환경에 있음). fging 프로세스(예: fg %4)는 내 입력이 표시되지 않지만 를 누른 후에도 계속 실행되는 대화형 셸을 생성합니다 <Enter>. test.py를 백그라운드에서 실행한 후 대화형 셸을 "정상적으로" 실행하려면 어떻게 해야 합니까?

(참고로 test.py에는

from time import sleep
a = 'hello world'
for i in range(10):
    sleep(1)
    print(a)

내 껍질은 다음과 같습니다

$ python3 -i test.py &
[4] 6708
$ hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
fg %4
python3 -i test.py
>>> 'hello world'
>>>

a첫 번째 프롬프트 이후에 입력했지만 아무 >>>것도 나타나지 않았습니다. )

-- 편집자 @muru --

fg에서 정상적으로 실행하고 bg로 보내면 다음이 제공됩니다.

$
$
$ python3 -i test.py
hello world
hello world
hello world
hello world
^Z
[4]+  Stopped                 python3 -i test.py
$ bg %4
[4]+ python3 -i test.py &
$ hello world
hello world
hello world
hello world
hello world
hello world
echo 'hello world'
hello world

[4]+  Stopped                 python3 -i test.py
$
$

쉘이 입력을 기다리고 있는데 echo 'hello world'10개의 "Hello World" 후에 입력했습니다.

답변1

이는 "경주" 배후의 Python 인터프리터가 test.py프로그램 실행을 마친 후 명령줄 셸을 사용하여 프롬프트를 표시하기 때문에 발생합니다.

당연히 Python은 당시 상호 작용이 허용되지 않았기 때문에 이 "전투"에서 패했습니다. 그러나 fg명령에 따라 완전히 재개될 수 없는 상태 로 자체 프롬프트를 남겨두기에는 너무 늦게 중지됩니다 .

이 문제를 해결하는 한 가지 방법은 Python 프로그램 끝에 다음 줄을 추가하는 것입니다.

import os, signal  # access os-level functions and UNIX-signals
os.kill(os.getpid(), signal.SIGSTOP)  # send myself the UNIX SIGSTOP signal

(물론 import일반적으로 프로그램 상단에 배치할 수도 있습니다.)

os.kill()줄은 마치 잘못된 순간에 대화형 상태로 들어가려고 시도하는 것처럼 Python 인터프리터를 정지시킵니다. 단, 이번에는 메시지를 표시하기 전에 자체적으로 실행되므로 일관성 없는 상태로 남아 있지 않습니다.

os.kill()명령줄 셸에서 Python이 중지되었음을 알리기 때문에 이 목표에 도달한 시기를 알 수 있습니다 . 이 시점에서 fg Python은 계속 실행되어 os.kill()자체 대화형 세션을 시작합니다.

bg중지된 후에는 재개 하지 마십시오 os.kill(). 그렇게 하면 커널이 백그라운드에서 상호 작용을 시도하기 위해 Python을 다시 중지하게 될 뿐입니다.

관련 정보