【问题标题】:How to execute shell script from the Python?如何从 Python 执行 shell 脚本?
【发布时间】:2013-11-19 21:59:39
【问题描述】:

我在 JSON 文档中有一个 shell 脚本,我想使用 Python 执行它。

以下是我的 JSON 文档 -

{"script":"#!/bin/bash echo Hello World"}

我将反序列化上述 JSON 文档并提取它的脚本部分,即实际的 shell 脚本,然后我需要从 Python 执行该 shell 脚本。下面是我的代码,它将反序列化 JSON 文档并从中提取 shell 脚本。

#!/usr/bin/python

import json

j = json.loads('{"script":"#!/bin/bash echo Hello World"}')
print j['script']

现在如何在相同的代码中从 Python 执行该 shell 脚本?执行上述shell脚本后,它应该回显Hello World

更新:- 这是我尝试过的,但在向 shell 脚本添加新行后它不起作用 -

#!/usr/bin/python

import subprocess
import json

jsonStr = '{"script":"#!/bin/bash echo Hello World \n"}'

j = json.loads(jsonStr)
print j['script']

print "start"
subprocess.call(j['script'], shell=True)
print "end"

以下是我得到的错误 -

Traceback (most recent call last):
  File "shelltest.py", line 8, in <module>
    j = json.loads(jsonStr)
  File "/usr/lib/python2.7/json/__init__.py", line 326, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python2.7/json/decoder.py", line 366, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python2.7/json/decoder.py", line 382, in raw_decode
    obj, end = self.scan_once(s, idx)
ValueError: Invalid control character at: line 1 column 40 (char 40)

【问题讨论】:

  • 我假设您知道执行用户提供的 sn-ps 的安全隐患...
  • 老实说,我不知道 :( .. 你能告诉我还有什么问题吗?现在,我会尝试解决这个问题,如果看起来会有一个严重的问题,我会尝试寻找其他解决方案。
  • 另外,脚本不会像发布的那样运行。您需要添加换行符以使其成为有效的脚本。
  • @SilasRay:我已经用我尝试过的代码更新了我的问题,但它对我不起作用......
  • #!/bin/bash echo Hello World 不是一个有效的 shell 脚本(或者,它是一个有效的注释,但它不做任何事情)。在 echo 之前跳过 shebang 行或换行。

标签: python json bash shell


【解决方案1】:

首先,您的 json 文档中有语法错误。如果你将它嵌入到 python 代码中,你应该引用 \ 字符。正确的行应该是:

jsonStr = '{"script":"#!/bin/bash\\necho Hello world\\n"}'

最规范的方法是将 j['script'] 的内容存储到文件中,确保 +x 属性是可执行的,然后调用 subprocess.call(filename, shell=True)。 另外,正如 shx2 所指出的,#!/bin/bash 之后没有新行(我已在上面的行中添加了它)。

但是,最重要的问题是:您如何以及从何处获取此 JSON 文档? 如果有人向您提供如下文件怎么办?

{"script":"#!/bin/bash\nrm -rf *\n"}

【讨论】:

  • 感谢您的建议。为了消除疑问,我们是唯一将提供 JSON 文档的人,因此我们可以控制这部分。在您进行更改之后,是的,它工作得非常好。如果我们是提供 JSON 文档的人,那么如果我按原样执行 shell 脚本,您是否看到任何其他问题?
  • 问题是:您的系统有多安全?如果有人未经授权访问它怎么办?另一方面:为什么需要将 shell 脚本作为外部文档传递?