python 3.5 - 在脚本终止后仍然运行subprocess.run

时间:2016-12-28 23:49:13

标签: python linux bash shell python-3.x

为什么在从此脚本运行命令{(1, 3): 64, (1, 4): 18, (1, 2): 10, (11, 11): 19, ...} 后终止带有ctrl+c的python脚本时,控件返回到终端会话,但在几分钟/秒后,shell命令重新出现在终端会话和来自subprocess.run('knife ec2 server create...', shell=True, check=True)的shell命令仍在运行?

我认为我在subprocess.run看到了同样的问题,例如os.system

os.system('ping 8.8.8.8')

^C

我也试过下面的代码,但是我收到了一个错误:

Waiting for EC2 to create the instance.....^CTraceback (most recent call last):
  File "t.py", line 177, in <module>
    subprocess.run(command, shell=True, check=True)
  File "/usr/lib/python3.5/subprocess.py", line 695, in run
    stdout, stderr = process.communicate(input, timeout=timeout)
  File "/usr/lib/python3.5/subprocess.py", line 1064, in communicate
    self.wait()
  File "/usr/lib/python3.5/subprocess.py", line 1658, in wait
    (pid, sts) = self._try_wait(0)
  File "/usr/lib/python3.5/subprocess.py", line 1608, in _try_wait
    (pid, sts) = os.waitpid(self.pid, wait_flags)
KeyboardInterrupt
$ ..............................................................................done

SSH Target Address: ec2()
Doing old-style registration with the validation key at /etc/chef/validation.pem...
Delete your validation key in order to use your user credentials instead

错误:

command = ('knife ec2 server create -N ' + fullname + ' -f ' + instance_type + ' -i ' + pem_file)...

p = subprocess.Popen(command, shell=True, stderr=subprocess.PIPE)
while True:
    out = p.stderr.read(1)
    if out == '' and p.poll() != None:
        break
    if out != '':
        sys.stdout.write(out)
        sys.stdout.flush()

是否有一种简单的方法可以使用`sys.stdout.write(out) TypeError: write() argument must be str, not bytes' pythonRuby一起运行shell命令?

由于

1 个答案:

答案 0 :(得分:1)

子进程模块产生一个新进程。当您将CTRL + C信号发送到您的python代码时,您将存在您的python应用程序,但子进程仍在运行,您的代码决定不等待该进程完成。

尝试在代码中捕获Ctrl + C信号,然后在现有应用程序之前使用Popen terminate调用结束子进程。

import shlex, subprocess
command_line = input()

args = shlex.split(command_line)
print(args)

p = subprocess.Popen(args) # Success!

Popen and subprocess docs

以下是终止呼叫的API文档:

Popen.Terminate

修改的 下面是python 2.7的示例演示代码,打印strout的代码部分并不适用于ping,因为它仍然会将ping结果输出到终端,但我把它放在那里供参考。

import subprocess
import signal
import sys

command = 'ping {0}'.format('8.8.8.8')
p = subprocess.Popen(command, shell=True, stderr=subprocess.PIPE)

# callback for the Ctrl+C signal
def signal_handler(signal, frame):
    print("CTRL+C received")
    p.kill() # or terminate
    p.wait()
    sys.exit(0)    

# register signal with the callback
signal.signal(signal.SIGINT, signal_handler)

# white subprocess hasn't finished
while p.poll() is None:
    out = p.communicate()
    print(out.stdoutdata)