将List传递给subprocess.run

问题描述 投票:0回答:1

我有一个包含列表的脚本 - 列表只是我想传递给subprocess.run的一些args

commands = ["bash command 1", "bash command 2",..]

这是我的代码

commands = ["bash command 1", "bash command 2",..]
process = subprocess.run([commands], stdout = subprocess.PIPE, shell = True)

如何将列表传递给我的subprocess.run?

这是Traceback

Traceback (most recent call last):
  File "./retesting.py", line 18, in <module>
    process = subprocess.run([commands], stdout = subprocess.PIPE, shell = True)
  File "/usr/lib/python3.5/subprocess.py", line 383, in run
    with Popen(*popenargs, **kwargs) as process:
  File "/usr/lib/python3.5/subprocess.py", line 676, in __init__
    restore_signals, start_new_session)
  File "/usr/lib/python3.5/subprocess.py", line 1221, in _execute_child
    restore_signals, start_new_session, preexec_fn)
TypeError: Can't convert 'list' object to str implicitly

我不知道我做错了什么,我尝试了各种各样的事情,所以我真的很感激任何帮助

python python-3.x bash subprocess
1个回答
1
投票

在使用shell=True之前,你必须了解它的作用。以the documentation for Popen为例。它指出:

shell参数(默认为False)指定是否使用shell作为要执行的程序。如果shell是True,建议将args作为字符串而不是序列传递。

在使用shell=True的Unix上,shell默认为/bin/sh。如果args是一个字符串,则该字符串指定通过shell执行的命令。这意味着字符串的格式必须与在shell提示符下键入时完全相同。这包括,例如,引用或反斜杠转义带有空格的文件名。如果args是一个序列,则第一个项指定命令字符串,并且任何其他项将被视为shell本身的附加参数。也就是说,Popen相当于:

Popen(['/bin/sh', '-c', args[0], args[1], ...])

在使用shell=True的Windows上,COMSPEC环境变量指定默认shell。您需要在Windows上指定shell=True的唯一时间是您希望执行的命令是否内置到shell中(例如dircopy)。您不需要shell=True来运行批处理文件或基于控制台的可执行文件。

无法一次执行一系列命令,您正在执行的是执行第一个命令以及将shell作为该shell的选项生成时传递的所有其他命令。

你想这样做:

for command in commands:
    subprocess.run(command, shell=True)

或者:您希望将命令序列作为单个脚本执行:

subprocess.run(';'.join(commands), shell=True)

这说:如果命令中的命令只是可执行文件,你应该真的避免使用shell=True并使用shlex.split来提供解析的参数列表。如果需要指定执行命令的目录,可以使用cwd参数Popen(或任何类似的函数)。

在你的情况下你想要的东西:

import os, subprocess

subprocess.run(['app', '--email', 'some-email', '--password', 'somepassword'], cwd=os.path.expanduser('~/app-cli'))
© www.soinside.com 2019 - 2024. All rights reserved.