从JSON文档在Python中执行shell脚本

时间:2013-12-28 00:50:25

标签: python json bash shell

我正在尝试使用子进程模块在Python中执行shell脚本。

下面是我的shell脚本,名为testing.sh

#!/bin/bash

hello=$jj1

echo $hello

echo $jj1
echo $jj2

for el1 in $jj3
do
    echo "$el1"
done

for el2 in $jj4
do
    echo "$el2"
done

现在我正在尝试用Python执行上面的shell脚本,所以我确实喜欢这个 -

subprocess.call(['./testing.sh'])

它工作正常。现在我想在这样的JSON文档中添加上面的脚本,然后执行它 -

json_script = '{"script":"above testing.sh script here"}'
j = json.loads(json_script)
shell_script = j['script']
subprocess.call(shell_script, shell=True)

但是每当我尝试时,它都会给我一个错误 -

下面是我的完整Python脚本,其中包含JSON文档中的上述testing.sh shell脚本 -

#!/usr/bin/python

import subprocess
import json
import socket
import os

jsonData = '{"pp": [0,3,5,7,9], "sp": [1,2,4,6,8]}'
jj = json.loads(jsonData)

print jj['pp']
print jj['sp']

os.putenv( 'jj1',  'Hello World 1')
os.putenv( 'jj2',  'Hello World 2')
os.putenv( 'jj3', ' '.join( str(v) for v in jj['pp']  ) )
os.putenv( 'jj4', ' '.join( str(v) for v in jj['sp']  ) )

print "start"

jsonDataaa = '{"script":"#!/bin/bash \\n hello=$jj1 \\n echo $hello \\n echo $jj1 \\n echo $jj2 \\n for el1 in $jj3 \\n do \\n echo "$el1" \\n done \\n for el2 in $jj4 \\n do \\n echo "$el2" \\n done"}'
j = json.loads(jsonDataaa)

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

以下是我得到的错误 -

 File "C:\Python27\lib\json\__init__.py", line 338, in loads
    return _default_decoder.decode(s)
  File "C:\Python27\lib\json\decoder.py", line 365, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "C:\Python27\lib\json\decoder.py", line 381, in raw_decode
    obj, end = self.scan_once(s, idx)
ValueError: Expecting , delimiter: line 1 column 113 (char 112) 

我应该得到预期的输出 -

[0, 3, 5, 7, 9]
[1, 2, 4, 6, 8]
start
Hello World 1
Hello World 2
0
3
5
7
9
1
2
4
6
8
end

更新: -

如果我有这样的jsonDataaa

jsonDataaa = '{"script":"#!/bin/bash \\n hello=$jj1 \\n echo $hello \\n echo $jj1 \\n echo $jj2 \\n"}'

然后它工作正常......我能够正确执行它..但如果我的jsonDataaa就像我在我的问题中提到的那样,那么只有它给了我一个错误。我想可能有一些我无法理解的语法错误。

3 个答案:

答案 0 :(得分:2)

它会给你这个错误,因为你的json字符串无效。具体来说,它包含未转义的引号。

如果将jsonDataaa赋值替换为:

,则它有效
jsonDataaa = '{"script":"#!/bin/bash \\n hello=$jj1 \\n echo $hello \\n echo $jj1 \\n echo $jj2 \\n for el1 in $jj3 \\n do \\n echo \\"$el1\\" \\n done \\n for el2 in $jj4 \\n do \\n echo \\"$el2\\" \\n done"}'

答案 1 :(得分:1)

这部分没有意义:

jsonDataaa = '{"script":"#!/bin/bash \\n hello=$jj1 \\n echo $hello \\n echo $jj1 \\n echo $jj2 \\n for el1 in $jj3 \\n do \\n echo "$el1" \\n done \\n for el2 in $jj4 \\n do \\n echo "$el2" \\n done"}'
j = json.loads(jsonDataaa)

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

你在这里做的是将一个文字字符串作为参数传递给subprocess.call(),但它需要一个程序名,而不是程序文本。所以你有两个选择:你可以将shell_script的内容写入NamedTemporaryFile并执行它,或者你可以在子进程中启动一个管道bash并从shell_script中提取它的标准输入。串。后一种方法是我更喜欢的,你可以在这里获得更多的帮助:Python - How do I pass a string into subprocess.Popen (using the stdin argument)?

P.S。:如果你使用三引号字符串,你可以让你的JSON看起来更好,多行和诸如此类。

答案 2 :(得分:0)

你也可以这样做:

subprocess.call(["/bin/sh", "-c", shell_script])

您将整个脚本作为单个命令行参数传递给sh。 即使shell_script中有换行符,这也应该有效;但如果它超过一定的大小(16K字节?类似的东西),它将不适合命令行。

编辑 - 使用subprocess.call(shell_script, shell=True)它实际上与我建议的相同,或多或少(可能其他选项的效果可能不同)。所以现在我猜测你的暗示引用\ n等可能不正确 - 请参阅下面的评论。

相关问题