在后台运行 python 脚本后打开交互式 python shell

在后台运行 python 脚本后打开交互式 python shell

python3 -i test.py运行 test.py 后打开交互式 python shell。但是,如果我尝试在后台运行它,python3 -i test.py & 作业会自动停止^C并显示

[4]+  Stopped                 python3 -i test.py

,之后我无法访问 python 的交互式 shell(test.py 中的变量仍然在环境中)。fging 进程(即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 以尝试在后台进行交互。

相关内容