简体   繁体   中英

python 3.5 - subprocess.run still running after the script was terminated

Why after I terminate a python script with ctrl+c while the command subprocess.run('knife ec2 server create...', shell=True, check=True) is running from this script, the control returns to the terminal session but after a few min/sec the shell command reappears in the terminal session and the shell command from subprocess.run still running?

I think I saw the same issue with os.system , for example 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

I tried also the below code but I got an error:

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()

error:

`sys.stdout.write(out) TypeError: write() argument must be str, not bytes'

Is there a simple way to run a shell command with python like Ruby with system() ?

Thanks

the subprocess module spawns a new process. when you send the CTRL+C signal to your python code, you are existing your python application but the subprocess is still running and your code decides not to wait for the process to finish.

Try catching the Ctrl+C signal in your code, and then use Popen terminate call to end the subprocess before existing your application.

import shlex, subprocess
command_line = input()

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

p = subprocess.Popen(args) # Success!

Popen and subprocess docs

Here is the API doc for the terminate call:

Popen.Terminate

Here is sample demo code for python 2.7, the section of the code that prints strout doesn't apply for ping, because it will still output the ping result to the terminal, but I placed it there for reference. 这是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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM