1 回答

TA貢獻1883條經(jīng)驗 獲得超3個贊
您需要單引號的原因是為了防止 shell 對您的參數(shù)進行任何擴展。這是一個問題,只有在使用shell=True. 如果未設置,shell 將永遠不會觸及您的參數(shù),也無需“保護”它們。
然而,shell 也負責stdout重定向(即[... '>', output_json])。不使用 shell,需要在 Python 代碼中處理重定向。然而,這就像將參數(shù)添加stdout=...到Popen.
總而言之,這意味著您的代碼可以重寫為
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,因為這會打開另一個針對代碼的攻擊向量,因為注入攻擊可以完全訪問 shell。此外,不使用 shell 的另一個小好處是,它將減少創(chuàng)建的子進程的數(shù)量,因為不需要額外的 shell 進程。
添加回答
舉報