我如何在Python中命名一个外部命令,就好像我把它写在一个<unk>或命令中?


当前回答

在Python 3.5+中使用子过程,以下是我在Linux上做的技巧:

import subprocess

# subprocess.run() returns a completed process object that can be inspected
c = subprocess.run(["ls", "-ltrh"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print(c.stdout.decode('utf-8'))

正如文档中提到的那样,PIPE 值是比特序列,为了正确显示它们,应考虑解码。

上述代码的结果是:

total 113M
-rwxr-xr-x  1 farzad farzad  307 Jan 15  2018 vpnscript
-rwxrwxr-x  1 farzad farzad  204 Jan 15  2018 ex
drwxrwxr-x  4 farzad farzad 4.0K Jan 22  2018 scripts
.... # Some other lines

其他回答

os.system 不允许您存储结果,所以如果您想要存储结果在某些列表或某些东西,一个 subprocess.call 工作。

我倾向于与shlex一起使用子过程(以处理引用的绳子的逃避):

>>> import subprocess, shlex
>>> command = 'ls -l "/your/path/with spaces/"'
>>> call_params = shlex.split(command)
>>> print call_params
["ls", "-l", "/your/path/with spaces/"]
>>> subprocess.call(call_params)

下面是我的两个百分点:在我看来,这是处理外部命令时最好的做法......

这些是执行方法的回报值......

pass, stdout, stderr = execute(["ls","-la"],"/home/user/desktop")

这是执行方法......

def execute(cmdArray,workingDir):

    stdout = ''
    stderr = ''

    try:
        try:
            process = subprocess.Popen(cmdArray,cwd=workingDir, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=1)
        except OSError:
            return [False, '', 'ERROR : command(' + ' '.join(cmdArray) + ') could not get executed!']

        for line in iter(process.stdout.readline, b''):

            try:
                echoLine = line.decode("utf-8")
            except:
                echoLine = str(line)

            stdout += echoLine

        for line in iter(process.stderr.readline, b''):

            try:
                echoLine = line.decode("utf-8")
            except:
                echoLine = str(line)

            stderr += echoLine

    except (KeyboardInterrupt,SystemExit) as err:
        return [False,'',str(err)]

    process.stdout.close()

    returnCode = process.wait()
    if returnCode != 0 or stderr != '':
        return [False, stdout, stderr]
    else:
        return [True, stdout, stderr]

从 OpenStack Neutron 中获取网络 ID:

#!/usr/bin/python
import os
netid = "nova net-list | awk '/ External / { print $2 }'"
temp = os.popen(netid).read()  /* Here temp also contains new line (\n) */
networkId = temp.rstrip()
print(networkId)

新网列表

+--------------------------------------+------------+------+
| ID                                   | Label      | CIDR |
+--------------------------------------+------------+------+
| 431c9014-5b5d-4b51-a357-66020ffbb123 | test1      | None |
| 27a74fcd-37c0-4789-9414-9531b7e3f126 | External   | None |
| 5a2712e9-70dc-4b0e-9281-17e02f4684c9 | management | None |
| 7aa697f5-0e60-4c15-b4cc-9cb659698512 | Internal   | None |
+--------------------------------------+------------+------+

印刷输出(networkId)

27a74fcd-37c0-4789-9414-9531b7e3f126

您可以使用 Popen 从子过程模块运行任何命令。

from subprocess import Popen

首先,一个命令对象是创建的,所有你想要运行的论点。 例如,在下面的剪辑中,指令对象是由所有论点组成的:

cmd = (
        "gunicorn "
        "-c gunicorn_conf.py "
        "-w {workers} "
        "--timeout {timeout} "
        "-b {address}:{port} "
        "--limit-request-line 0 "
        "--limit-request-field_size 0 "
        "--log-level debug "
        "--max-requests {max_requests} "
        "manage:app").format(**locals())

然后这个命令对象与Popen一起使用,以启动一个过程:

process = Popen(cmd, shell=True)

这个过程也可以根据任何信号结束,使用下面的代码线:

Popen.terminate(process)

你可以等到完成上述命令的执行:

process.wait()