输出子进程调用的命令行?

时间:2013-02-12 16:19:57

标签: python command-line subprocess popen

我正在使用subprocess.Popen调用,在另一个问题中我发现我误解了Python如何为命令行生成参数。

我的问题
有没有办法找出实际的命令行是什么?

示例代码: -

proc = subprocess.popen(....)
print "the commandline is %s" % proc.getCommandLine()

你会怎么写getCommandLine

3 个答案:

答案 0 :(得分:55)

这取决于您使用的Python版本。 In Python3.3,arg保存在proc.args

proc = subprocess.Popen(....)
print("the commandline is {}".format(proc.args))

在Python2.7 the args not saved中,它只是传递给其他函数,如_execute_child。因此,在这种情况下,获取命令行的最佳方法是在拥有它时保存它:

proc = subprocess.Popen(shlex.split(cmd))
print "the commandline is %s" % cmd

请注意,如果您拥有 list 参数(例如shlex.split(cmd)返回的事物类型),那么您可以使用cmd恢复命令行字符串subprocess.list2cmdline未记录的函数In [14]: import subprocess In [15]: import shlex In [16]: cmd = 'foo -a -b --bar baz' In [17]: shlex.split(cmd) Out[17]: ['foo', '-a', '-b', '--bar', 'baz'] In [18]: subprocess.list2cmdline(['foo', '-a', '-b', '--bar', 'baz']) Out[19]: 'foo -a -b --bar baz'

{{1}}

答案 1 :(得分:3)

我的问题的正确答案实际上是 IS 没有命令行。子流程的关键在于它通过IPC完成所有工作。 list2cmdline的确尽可能接近,但实际上最好的办法是查看“args”列表,并且知道这将是被调用程序中的argv。

答案 2 :(得分:1)

美观且可扩展的方法

我一直在使用这样的东西:

#!/usr/bin/env python3

import os
import shlex
import subprocess
import sys

def run_cmd(cmd, cwd=None, extra_env=None, extra_paths=None, dry_run=False):
    if extra_env is None:
        extra_env = {}
    newline_separator = ' \\\n'
    out = []
    kwargs = {}
    env = os.environ.copy()

    # cwd
    if 'cwd' is not None:
        kwargs['cwd'] = cwd

    # extra_env
    env.update(extra_env)
    for key in extra_env:
        out.append('{}={}'.format(shlex.quote(key), shlex.quote(extra_env[key])) + newline_separator)

    # extra_paths
    if extra_paths is not None:
        path = ':'.join(extra_paths)
        if 'PATH' in env:
            path += ':' + env['PATH']
        env['PATH'] = path
        out.append('PATH="{}:${{PATH}}"'.format(':'.join(extra_paths)) + newline_separator)

    # Command itself.
    for arg in cmd:
        out.append(shlex.quote(arg) + newline_separator)

    # Print and run.
    kwargs['env'] = env
    print('+ ' + '  '.join(out) + ';')
    if not dry_run:
        subprocess.check_call(cmd, **kwargs)

run_cmd(
    sys.argv[1:],
    cwd='/bin',
    extra_env={'ASDF': 'QW ER'},
    extra_paths=['/some/path1', '/some/path2']
)

样品运行:

./a.py echo 'a b' 'c d' 

输出:

+ ASDF='QW ER' \
  PATH="/some/path1:/some/path2:${PATH}" \
  echo \
  'a b' \
  'c d' \
;
a b c d

功能摘要:

  • 使巨大的命令行可读,每行只有一个选项
  • +之类的命令中添加sh -x,以便用户可以轻松区分其输出中的命令
  • 显示cd,以及额外的环境变量(如果已将其分配给命令)。这些仅在给出的情况下打印,从而生成最小的shell命令。

所有这些功能使用户可以轻松地手动复制命令,以在出现故障时运行它们,或者查看正在发生的事情。

在Python 3.5.2,Ubuntu 16.04上测试。 GitHub upstream