简体   繁体   English

从另一个python脚本调用面向命令行的脚本

[英]Call command-line oriented script from another python script

I am using a script written in Python that uses the argparse module to get it's arguments from command line. 我使用的是用Python编写的脚本,它使用argparse模块从命令行获取它的参数。 I try to modify this file as less as possible as various people work on it. 我尝试尽可能少地修改此文件,因为各种人都在使用它。

Ex: script is called CLscript.py and I call it with 例如:脚本名为CLscript.py,我用它来调用它

python CLscript.py -option1 arg1 -flag1 -option2 arg2

But I'm facing the case where I would like to automate things one level higher and automatically launch this script with wide range of script-generated arguments. 但我面临的情况是,我希望自动化更高级别的东西,并使用各种脚本生成的参数自动启动此脚本。

I would like to keep using all the existing organisation of options and flags available in this script. 我想继续使用此脚本中现有的所有选项和标志组织。

For example, when I run CLscript.py from topLevelScript.py through : 例如,当我从topLevelScript.py运行CLscript.py时:

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

,and I see from the output that something is going wrong, I stop the execution topLevelScript.py, but CLscript.py continue to run independently in another python process that I Have to kill manually. ,我从输出中看到出现问题,我停止执行topLevelScript.py,但CLscript.py继续在另一个我必须手动杀死的python进程中独立运行。 I cannot neither launch topLevelScript.py in debug mode to stop at a breakpoint in CLscript.py. 我无法在调试模式下启动topLevelScript.py以在CLscript.py中的断点处停止。

I would like to do this all from inside python, without building a command line string and launching CLscript.py with a subprocess. 我想从python内部完成所有这些操作,无需构建命令行字符串并使用子进程启动CLscript.py。 Every call would remains attached to the same original launch, just like a function call, and not creating multiple python threads like it would do with a subprocess.call() . 每个调用都将保持附加到同一个原始启动,就像函数调用一样,而不是像使用subprocess.call()那样创建多个python线程。

Something like passing a list of string with options, flags and arguments somehow to the script maybe? 有点像是以某种方式向脚本传递带有选项,标志和参数的字符串列表吗?

Is there something like 有没有类似的东西

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

Would something like this work? 会这样的吗? Extract most of your code into a new function that expects arguments similar to the ones you send in via the command line. 将大部分代码提取到一个新函数中,该函数需要与通过命令行发送的参数类似的参数。 Then write a new function that gathers the command line arguments and sends them to the first function ... 然后编写一个新函数,收集命令行参数并将它们发送到第一个函数...

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

Then your other scripts can just call the main function. 然后你的其他脚本可以调用main函数。

First of all, use http://docs.python.org/2/library/subprocess.html#subprocess.Popen and not subprocess.call() : 首先,使用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
)

Please notice that as the first argument you pass an array of strings just like you want. 请注意,作为第一个参数,您可以按照自己的意愿传递array of strings
Secondly redirection of standard file descriptors will be important. 其次,重定向标准文件描述符非常重要。 See http://docs.python.org/2/library/subprocess.html#subprocess.PIPE . 请参见http://docs.python.org/2/library/subprocess.html#subprocess.PIPE
Now you have child variable which holds instance of Popen class. 现在你有了一个child变量,它包含了Popen类的实例。
What you can do with this instance? 你可以用这个实例做什么?

# 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

You said you wanted to detect if something goes wrong in the child process from it's output. 你说你想从它的输出中检测子进程中是否出现问题。
Don't you find stdout and stderr quite useful for this case? 难道你不觉得stdoutstderr对这个案子非常有用吗?
Now you wanted to terminate the child if you detected that something went wrong. 现在你想要在发现问题出现时终止孩子。

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

If in the end you are sure that everything went well but you want to let child finalize normally, you should use 如果你最终确定一切顺利,但你想让孩子正常完成,你应该使用

child.wait()

or even better 甚至更好

child.communicate()

because communicate will handle lots of output properly. 因为communicate会正确处理大量输出。

Good luck! 祝好运!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在命令行中从另一个 python 脚本调用 Python 脚本? - How to call a Python script in command line from another python script? 如何从另一个脚本中将命令行 arguments 传递给 python 脚本? - How to pass command-line arguments to a python script from within another script? 使用命令行 arguments 在另一个内部调用一个 Python 脚本 - Calling one Python script inside another with command-line arguments 如何从Python脚本访问命令行参数? - How to access command-line arguments from a Python script? 从另一个目录中存在的命令行调用python脚本 - Call python script from command line, which exists in another directory 如何从命令行或其他脚本运行 python 脚本 - How to run python script from command line or from another script python终止带有有用消息的Python命令行脚本 - Terminating a Python command-line script with helpful messages, pythonically 如何将命令行参数作为字符串传递给从C ++执行的嵌入式Python脚本? - how to pass command-line arguments as a string to an embedded Python script executed from C++? 如何从命令行Python脚本中保存LibreOffice Calc电子表格中的所有工作表 - How can I save ALL sheets in a LibreOffice Calc Spreadsheet from a command-line Python script 如何将命令行参数传递给从Python执行的Perl脚本 - How to pass command-line parameters to a Perl script executed from Python
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM