1 回答

TA貢獻(xiàn)1883條經(jīng)驗(yàn) 獲得超3個(gè)贊
您需要單引號(hào)的原因是為了防止 shell 對(duì)您的參數(shù)進(jìn)行任何擴(kuò)展。這是一個(gè)問(wèn)題,只有在使用shell=True. 如果未設(shè)置,shell 將永遠(yuǎn)不會(huì)觸及您的參數(shù),也無(wú)需“保護(hù)”它們。
然而,shell 也負(fù)責(zé)stdout重定向(即[... '>', output_json])。不使用 shell,需要在 Python 代碼中處理重定向。然而,這就像將參數(shù)添加stdout=...到Popen.
總而言之,這意味著您的代碼可以重寫(xiě)為
import os
import subprocess
# Still define first command line argument with triple quotes for readability
# Note that there are no single quotes though
jq_filter = """INDEX(.images[]; .id) as $imgs | {
"filename_with_label" : [
.annotations[]
| select(.attributes.type=="letter" )
| $imgs[.image_id] + {label:.text}
| {id:.id} + {filename:.file_name} + {label:.label} ] }"""
input_json_files = ["image_data_annotation.json"]
output_json_files = []
for input_json in input_json_files:
print("Processing %s" % (input_json))
filename, ext = os.path.splitext(input_json)
output_json = filename + "_with_label" + ext
output_json_files.append(output_json)
print("output file is : %s" % (output_json))
# Keep command as list, since this is what we need when NOT using shell=True
# Note also that the redirect and the output file are not parts of the argument list
jq_command = ['jq', jq_filter, input_json]
# shell keyword argument should NOT be set True
# Instead redirect stdout to an out_file
# (We must open the file for writing before redirecting)
with open(output_json, "w") as out_file:
subprocess.Popen(jq_command, stdout=out_file)
通常建議不要使用shell=True,因?yàn)檫@會(huì)打開(kāi)另一個(gè)針對(duì)代碼的攻擊向量,因?yàn)樽⑷牍艨梢酝耆L問(wèn) shell。此外,不使用 shell 的另一個(gè)小好處是,它將減少創(chuàng)建的子進(jìn)程的數(shù)量,因?yàn)椴恍枰~外的 shell 進(jìn)程。
添加回答
舉報(bào)