我试图通过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
,cmd2
和cmd3
作为cmd1
的命令行参数。相反,您希望执行单个shell命令序列;您在这里尝试做的一些事情需要shell,所以您确实需要shell=True
,它规定使用单个字符串作为输入,而不是由命令及其参数组成的列表。
(Windows在后台有一些挑剔的处理,这使得使用字符串列表作为shell=True
的第一个参数并非完全不可能;但这确实不便携,也不明显。只是不。)
关于这里对shell=True
的需求,像call
和cd
(以及波恩家族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是sh
或bash
,那么相同的语法看起来像
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()
,特别是如果你对子过程的理解不是很复杂的话。