python3 -i test.py
运行 test.py 后打开交互式 python shell。但是,如果我尝试在后台运行它,python3 -i test.py &
作业会自动停止^C
并显示
[4]+ Stopped python3 -i test.py
,之后我无法访问 python 的交互式 shell(test.py 中的变量仍然在环境中)。fg
ing 进程(即fg %4
)会导致一个交互式 shell,其中看不到我的输入,但在按 后仍然运行<Enter>
。在后台运行 test.py 后如何“正常”运行交互式 shell?
(作为参考,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
$
$
shell 正在等待输入,我echo 'hello world'
在 10 个“Hello World”之后输入。
答案1
发生这种情况是因为后台的 Python 解释器一旦完成执行test.py
程序就会与命令行 shell 进行“竞争”提示。
很自然,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()
达到此目标,因为命令行 shell 会通知您 Python 已停止。此时fg
,Python 将继续运行os.kill()
,从而开始其自己的交互式会话。
不要bg
在它被 Stopped 后恢复它os.kill()
,因为这样做只会使内核再次停止 Python 以尝试在后台进行交互。