[英]Executing a shell script in Python from the JSON document
我正在嘗試使用子進程模塊在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如我在問題中提到的那樣,那么只有它會給我一個錯誤。 我認為可能存在某些語法錯誤,我無法理解。
由於您的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"}'
這部分不太有意義:
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並執行,或者可以在子shell_script
啟動管道bash
並將shell_script
stdin作為字符串輸入。 我更喜歡使用后一種方法,您可以在此處獲得更多幫助: Python-如何將字符串傳遞到subprocess.Popen中(使用stdin參數)?
PS:如果您使用三引號引起來的字符串,則可以使您的JSON看起來更好,可以在多行上顯示。
您也可以這樣做:
subprocess.call(["/bin/sh", "-c", shell_script])
您正在將整個腳本作為單個命令行參數傳遞給sh。 即使shell_script中有換行符,它也應該起作用。 但是,如果它大於某個大小(16K字節?類似的東西),它將不適合在命令行中使用。
編輯-通過使用subprocess.call(shell_script, shell=True)
它實際上與我建議的相同,或多或少(也許其他選項的效果可能不同)。 因此,現在我猜想\\ n等的引用可能不正確,如您所暗示-請參閱下面的注釋。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.