【问题标题】:Call command-line oriented script from another python script从另一个 python 脚本调用面向命令行的脚本
【发布时间】:2014-03-24 11:37:38
【问题描述】:

我正在使用一个用 Python 编写的脚本,该脚本使用 argparse 模块从命令行获取它的参数。我尝试尽可能少地修改这个文件,因为不同的人都在处理它。

例如:脚本被称为 CLscript.py,我用

来调用它
python CLscript.py -option1 arg1 -flag1 -option2 arg2

但我正面临这样一种情况,即我希望将事情自动化更高一级并使用各种脚本生成的参数自动启动此脚本。

我想继续使用此脚本中可用的所有现有选项和标志组织。

例如,当我从 topLevelScript.py 运行 CLscript.py 时:

subprocess.call("python CLscript.py -option1 arg1 -flag1 -option2 arg2")

,我从输出中看到出了点问题,我停止执行 topLevelScript.py,但 CLscript.py 继续在另一个我必须手动终止的 python 进程中独立运行。我不能在调试模式下启动 topLevelScript.py 以在 CLscript.py 的断点处停止。

我想在 python 内部完成这一切,而不需要构建命令行字符串并使用子进程启动 CLscript.py。 每个调用都将保持连接到相同的原始启动,就像函数调用一样,而不是像使用 subprocess.call() 那样创建多个 python 线程。

可能会以某种方式将带有选项、标志和参数的字符串列表传递给脚本?

有没有类似的

import CLscript.py
CLsimulator(CLscript,["-option1",arg1,"-flag1","-option2",arg2])

【问题讨论】:

  • “创建多个 python 线程,就像使用 subprocess.call() 一样” - subprocess 模块与线程无关。
  • 其实我也不是很清楚你想做什么,能不能说的详细点或者举个例子?
  • “类似于传递带有选项、标志和参数的字符串列表”-subprocess.call() 的第一个参数是字符串列表。
  • 我编辑了我的问题以使其更清晰
  • @ElmoVanKielmo 查看我的编辑,了解为什么我尽量不使用 subprocess.call()

标签: python command-line command-line-arguments


【解决方案1】:

首先,使用http://docs.python.org/2/library/subprocess.html#subprocess.Popen 而不是subprocess.call()

import subprocess

child = subprocess.Popen(
    ['python', 'CLscript.py', '-option1', 'arg1', '-flag1', '-option2', 'arg2'],
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE
)

请注意,您传递的第一个参数是 array of strings,就像您想要的那样。
其次,标准文件描述符的重定向很重要。见http://docs.python.org/2/library/subprocess.html#subprocess.PIPE
现在你有 child 变量,它包含 Popen 类的实例。
你可以用这个实例做什么?

# Check if child is terminated and possibly get the returncode
child.poll()
# Write to child's standard input by a file-like object accessible with
child.stdin
# Read child's standard output and standard error by file-like objects accesible with
child.stdout
child.stderr

您说您想从子进程的输出中检测子进程是否有问题。
你不觉得stdoutstderr 在这种情况下很有用吗?
现在,如果您检测到出现问题,您想终止孩子。

child.kill()
child.terminate()
child.send_signal(signal)

如果最后你确定一切顺利但你想让孩子正常完成,你应该使用

child.wait()

甚至更好

child.communicate()

因为communicate 将正确处理大量输出。

祝你好运!

【讨论】:

  • 好的,我之前认为 Popen 是一些低级的东西,我不应该触摸并使用 call 代替,但是像这样它似乎并不那么复杂。谢谢!
  • @antoine subprocess.call(...) 实际上是 child = subprocess.Popen(...) 的简写,没有管道到 stdin、stdout、stderr,后跟 child.wait()
【解决方案2】:

这样的东西会起作用吗?将您的大部分代码提取到一个新函数中,该函数需要与您通过命令行发送的参数相似的参数。然后编写一个新函数来收集命令行参数并将它们发送到第一个函数...

def main(foo, bar):
    a = foo + bar
    print a

def from_command_line():
    foo, bar = get_command_line_args()
    main(foo, bar)

if __name__ == "__main__":
    from_command_line()

那么你的其他脚本就可以调用主函数了。

【讨论】:

  • 这将是处理问题的好方法,我喜欢这个主意,谢谢。尽管如此,在我的特殊情况下,因为它是一个合作项目,我无法修改此文件,Elmo 的回答允许我这样做。
猜你喜欢
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
  • 2013-03-13
  • 1970-01-01
  • 2015-11-02
  • 1970-01-01
  • 2016-09-03
  • 1970-01-01
相关资源
最近更新 更多