简体   繁体   English

Flask 应用程序中的 Python subprocess.run 失败 [Errno 2] 没有这样的文件或目录:'ls':'ls'

[英]Python subprocess.run inside Flask app failure [Errno 2] No such file or directory: 'ls': 'ls'

What is needed to use subprocess.run() inside a Flask app?在 Flask 应用程序中使用 subprocess.run() 需要什么?

Even a simple example from https://docs.python.org/3.6/library/subprocess.html fails.甚至来自https://docs.python.org/3.6/library/subprocess.html的简单示例也失败了。

process = subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE)
output = process.stdout
app.logger.info(f"Process output: {output}")

  File "./main.py", line 209, in process_pdf
    process = subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE)
  File "/usr/lib/python3.6/subprocess.py", line 423, in run
    with Popen(*popenargs, **kwargs) as process:
  File "/usr/lib/python3.6/subprocess.py", line 729, in __init__
    restore_signals, start_new_session)
  File "/usr/lib/python3.6/subprocess.py", line 1364, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'ls': 'ls'

Python 3.6.8 (on Ubuntu 18.04LTS) Python 3.6.8(在 Ubuntu 18.04LTS 上)

Flask is being served by uwsgi (from nginx) Flask 由 uwsgi(来自 nginx)提供服务

I started from more complicated examples, trying with shell=True and other arguments, but nothing seems to be working.我从更复杂的例子开始,尝试使用 shell=True 和其他参数,但似乎没有任何效果。

subprocess.run() works just fine when called from command line sub.py subprocess.run() 从命令行 sub.py 调用时工作正常

process = subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE)
output = process.stdout
print(f"Results {output}")

Results b'crw-rw-rw- 1 root root 1, 3 Nov 28 15:10 /dev/null\n'

Within Flask I can use old os.popen - no results though在 Flask 中,我可以使用旧的 os.popen - 虽然没有结果

stream = os.popen('ls -l /dev/null')
output = stream.readlines()

app.logger.info(f"Process output: {output}")

EDIT: Thanks to @furas and @Dursug for pointing me in the right direction.编辑:感谢@furas 和@Dursug 为我指明了正确的方向。 It seems like lack of shell issue for www-data. www-data 似乎缺少 shell 问题。

So what would be the most Pythonic / Flask way of solving this?那么解决这个问题的最 Pythonic / Flask 方法是什么?

PS I want to run specific external programs such as imagemagick, pdftotext, but I want to avoid wrappers/bindings (sometimes there are none). PS 我想运行特定的外部程序,如 imagemagick、pdftotext,但我想避免包装器/绑定(有时没有)。

This did turn out to be an enviroment issue for www-data which only had access to virtualenv path where Flask app was residing.这确实是 www-data 的环境问题,它只能访问 Flask 应用程序所在的 virtualenv 路径。

Solved by editing通过编辑解决

/etc/systemd/system/myproject.service and adding :/usr/bin:/bin as in /etc/systemd/system/myproject.service 并添加 :/usr/bin:/bin 如

Environment="PATH=/home/myname/myproject/myprojectenv/bin:/usr/bin:/bin"

Then restarted nginx and service然后重启nginx和服务

As suggested by one of the answers on uWSGI python subprocess chrome/firefox failed .正如uWSGI python subprocess chrome/firefox failed的答案之一所建议的那样。

The question remains open whether this is the best practice for Flask.这是否是 Flask 的最佳实践仍然存在疑问。

Theoretically this opens up a potential vulnerability if client can find a way to run an arbitrary command.从理论上讲,如果客户端可以找到运行任意命令的方法,这会打开一个潜在的漏洞。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM