python子进程多个命令与win路径



我试图通过conda触发python脚本的执行。

然后我将捕获输出并将其报告到执行命令的命令提示符。

这是最简单的概念

wrap.py -包装器可以多次执行以下脚本

import subprocess
def wrap():
while True:
cmd1=r"call C:\Users\my_user\anaconda3\Scripts\activate.bat"
cmd2=r"cd C:\myfolder\mysubfolder"
cmd3=r"C:\Users\my_user\anaconda3\python.exe C:\myfolder\mysubfolder\test.py"
proc = subprocess.run([cmd1,cmd2,cmd3])
if __name__ == '__main__':
wrap()

test.py -必须执行的脚本

def mytest():
print("success")
if __name__ == '__main__':
mytest()

由于mytest打印成功一次,我希望包装器(在anaconda上运行)的输出为

(base) C:myfoldermysubfolder> python wrap.py
success
success
success
...

I tried with

1 -子过程。Popen

3 -使用列表["第一个命令"第二个命令","第三个命令"]或单个字符串"first;second;third">

4 -使用或删除" "在字符串前面,这里的空格打破了游戏

5 -使用单引号或双引号

6-在my_user中下划线也会导致编码错误

我实际上尝试了至少20个不同的stackoverflow解决方案。但它们都不适合我。我还阅读了python文档的子处理页面,但这没有帮助。

任何提示都很感激,我迷路了。

语法subprocess.run([cmd1, cmd2, cmd3])表示运行cmd1,cmd2cmd3作为cmd1的命令行参数。相反,您希望执行单个shell命令序列;您在这里尝试做的一些事情需要shell,所以您确实需要shell=True,它规定使用单个字符串作为输入,而不是由命令及其参数组成的列表。

(Windows在后台有一些挑剔的处理,这使得使用字符串列表作为shell=True的第一个参数并非完全不可能;但这确实不便携,也不明显。只是不。)

关于这里对shell=True的需求,像callcd(以及波恩家族shell中的source.)这样的命令是shell内置的,它们不作为单独的二进制文件存在;如果你没有shell=True,你只会得到&;command not found&;或者你当地的同等机构。(在其他情况下,你应该尽量避免shell=True。但这不是那种情况;在这里,如果没有重大的代码更改,这确实是不可避免的。

如果你的shell是cmd,我猜命令可能看起来像

subprocess.run(
r"call C:Usersmy_useranaconda3Scriptsactivate.bat & C:Usersmy_useranaconda3python.exe C:myfoldermysubfoldertest.py",
shell=True)

或者等价的字符串前面没有r并且所有反斜杠都是双斜杠;r"..."字符串和常规"..."字符串之间的唯一区别是前者允许您放入文字反斜杠,而后者要求您转义它们;在前一种情况下,字符串中的所有都是文字,而在后一种情况下,您可以使用符号符号,如n用于换行字符,t用于制表符等。

在Python中,使用单引号还是双引号并不重要;显然,只要使用相同的开、闭引号,就可以在它们之间自由切换。如果需要在字符串中使用单引号,请使用双引号,这样就不必对引号进行反斜杠转义,反之亦然。还有三引号字符串,它可以接受任意一个引号字符,但允许跨多行,即包含不带引号的字面换行符。

如果您首选的shell是shbash,那么相同的语法看起来像

subprocess.run(r"""
source C:Usersmy_useranaconda3Scriptsactivate.bat &&
C:Usersmy_useranaconda3python.exe C:myfoldermysubfoldertest.py""",
shell=True)

在这两种情况下我都省略了cd,因为代码中似乎没有任何内容要求子进程在特定目录中运行。如果您确实有这个需求,您可以在shell=True之后添加cwd=r'C:myfoldermysubfolder',以便在单独的目录中运行整个子进程。

存在subprocess.run()设施不足的情况,需要下拉至裸subprocess.Popen(),并自行完成周边管道;但这显然不是上述情形之一。如果可以的话,你应该远离Popen(),特别是如果你对子过程的理解不是很复杂的话。

最新更新