add cmd.terminate; improve cmd doc

This commit is contained in:
Prodesire 2017-12-24 08:21:09 +08:00
parent 4c4018e193
commit bceb5eb6e2
3 changed files with 55 additions and 5 deletions

View File

@ -1,7 +1,16 @@
Cmd
-------
---
.. py:function:: pydu.cmd.run(cmd, wait=True, shell=True)
.. py:class:: pydu.cmd.TimeoutExpired(cmd, timeout, output=None, stderr=None)
This exception is raised when the timeout expires while waiting for a
child process.
Attributes:
cmd, output, stdout, stderr, timeout
.. py:function:: pydu.cmd.run(ccmd, wait=True, env=None, shell=False, timeout=None, timeinterval=1)
Run cmd based on ``subprocess.Popen``.
@ -23,13 +32,28 @@ Cmd
<subprocess.Popen at 0x22e4010f9e8>
.. py:function:: pydu.cmd.run(cmd, wait=True, shell=False, env=None, timeout=None, timeinterval=1)
Run cmd with English character sets environment, so that the output will
be in English.
Parameters are same with ``run``.
.. py:function:: pydu.cmd.terminate(pid)
Terminate process by given ``pid``.
On Windows, using `kernel32.TerminateProcess` to kill.
On other platforms, using `os.kill` with `signal.SIGTERM` to kill.
.. py:function:: pydu.cmd.cmdline_argv()
Get command line argv of self python process. On Windows when using Python 2,
``cmdline_argv`` is implemented by using ``shell32.GetCommandLineArgvW`` to get
sys.argv as a list of Unicode strings.
On other system or using Python 3, ``cmdline_argv`` is same to ``sys.argv``.
On other platforms or using Python 3, ``cmdline_argv`` is same to ``sys.argv``.
>>> from pydu.cmd import cmdline_argv
>>> cmdline_argv()

View File

@ -1,6 +1,7 @@
import os
import sys
import time
import signal
import subprocess
from subprocess import Popen, PIPE, STDOUT
@ -86,6 +87,23 @@ def run_with_en_env(cmd, wait=True, env=None, shell=False, timeout=None, timeint
timeout=timeout, timeinterval=timeinterval)
def terminate(pid):
"""
Terminate process by given pid.
On Windows, using Kernel32.TerminateProcess to kill.
On Other platforms, using os.kill with signal.SIGTERM to kill.
"""
if WINDOWS:
# http://code.activestate.com/recipes/347462-terminating-a-subprocess-on-windows/
import ctypes
PROCESS_TERMINATE = 1
handle = ctypes.windll.kernel32.OpenProcess(PROCESS_TERMINATE, False, pid)
ctypes.windll.kernel32.TerminateProcess(handle, -1)
ctypes.windll.kernel32.CloseHandle(handle)
else:
os.kill(pid, signal.SIGTERM)
if PY2 and WINDOWS:
# enable passing unicode arguments from command line in Python 2.x
# https://stackoverflow.com/questions/846850/read-unicode-characters

View File

@ -1,9 +1,9 @@
import sys
import pytest
from pydu.platform import WINDOWS
import time
from pydu.compat import string_types
from pydu.string import safeunicode
from pydu.cmd import TimeoutExpired, run, run_with_en_env, cmdline_argv
from pydu.cmd import TimeoutExpired, run, run_with_en_env, terminate, cmdline_argv
def test_run():
@ -32,6 +32,14 @@ def test_run_with_en_env():
assert output.decode('ascii')
def test_terminate():
p = run('{} -c "import time; time.sleep(1)"'.format(sys.executable),
wait=False, shell=True)
terminate(p.pid)
time.sleep(0.1)
assert p.poll() is not None
def test_cmdline_argv():
argv = cmdline_argv()
for s in argv[1:]: