Python 在已部署的web应用程序上调用shell命令时出现意外行为
我正在部署一个flask应用程序,其中将启动一个多处理进程。在这个进程中,我通过subprocess.call()调用一个shell命令。脚本在本地主机上执行时运行良好,当与nginx和gunicorn一起部署时,flask应用程序将按预期运行,直到子进程启动,然后我收到以下错误日志:Python 在已部署的web应用程序上调用shell命令时出现意外行为,python,shell,flask,subprocess,multiprocessing,Python,Shell,Flask,Subprocess,Multiprocessing,我正在部署一个flask应用程序,其中将启动一个多处理进程。在这个进程中,我通过subprocess.call()调用一个shell命令。脚本在本地主机上执行时运行良好,当与nginx和gunicorn一起部署时,flask应用程序将按预期运行,直到子进程启动,然后我收到以下错误日志: DEBUG:root:start to run command DEBUG:root:(<class 'FileNotFoundError'>, FileNotFoundError(2, "No su
DEBUG:root:start to run command
DEBUG:root:(<class 'FileNotFoundError'>, FileNotFoundError(2, "No such file or directory: 'java -jar ábsolute/path/to/jar/file')
Process(
target=decode_upload,
args=(
path_to_blf,
path_to_dbc_folder,
path_to_splitted,
path_to_decoder,
system_layout,
dc_doc,
dc_id,
file_type,
)
).start()
进程到达此行时失败
subprocess.call(command)
如果我尝试从命令行调用“command”,它将毫无问题地工作
from subprocess import Popen
command='your complete command as you paste on cmd'
p1=Popen(command,Shell=True)
这将帮助您以完整字符串的形式运行命令。正确的解决方案是将命令作为已解析参数的列表传递。您需要了解shell如何处理引用和参数拆分来正确执行此操作 作为一个快速欺骗
printf "'%s'\n" your command line here
在shell中,您应该能够很好地了解shell如何扩展参数。比如说
bash$ printf "'%s'\n" java -jar "/path/complex path with spaces.jar" \* \>\<
'java'
'-jar'
'/path/complex path with spaces.jar'
'*'
'><'
嗨,谢谢你的回答。是的,错误消失了,但仍然不会执行该命令。我通过使用p=subprocess.run(“ls”,shell=True,stdout=PIPE)、logging.debug(p.stdout)从这个命令捕获stdout。但我收到一条消息DEBUG:root:b“”,这意味着日志文件中没有任何内容。该命令似乎尚未运行。没有,错误再次出现。但没有运行任何命令。我尝试了os.system(命令),但什么也没有发生,但如果我在终端中运行该命令,它将正常工作。
Popen()
只是启动命令,但将其作为子进程运行。call()
包装器(或在较新的Python版本中run()
)进行必要的管理,正确等待进程完成并有选择地将其输出存储在某处等。您希望避免底层的Popen()
method,除非现有的高级包装器方法都不适合您的用例。是的,它现在可以工作了。但是调用这两个API有什么区别吗?我也尝试了p1=Popen([command\u 1,command\u 2,…]),但它也不起作用。另请参阅为什么要避免shell=True
谢谢!这真的很有帮助!
bash$ printf "'%s'\n" java -jar "/path/complex path with spaces.jar" \* \>\<
'java'
'-jar'
'/path/complex path with spaces.jar'
'*'
'><'
subprocess.call(['java', '-jar', '/path/complex path with spaces.jar', '*', '><'])
command = [SOFTWARE_COMMAND, path_to_decoder, '--blf={}'.format(path_to_blf)]
for dbc_file_name in DBC_FILE_NAME_LIST:
command.append("--dbc={}".format(
os.path.join(path_to_dbc_folder, dbc_file_name)))
command.append("--out={}".format(path_to_splitted))