명령 줄 인수와 함께 popen을 사용하는 방법은 작은 따옴표와 큰 따옴표를 포함합니까?

홍숙

python3에서 다음 jq명령 을 실행하고 싶습니다 subprocess.Popen().

$ jq  '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}
     ]
   }' image_data_annotation.json > image_data_annotation_with_label.json

첫 번째 명령 줄 인수에는 작은 따옴표 안에 점, 달러 기호, 큰 따옴표가 포함되어 있습니다. 참고로, jqjson 파일 처리를위한 JSON 프로세서 유틸리티입니다.

jq유틸리티로 JSON 파일 처리를 자동화하기 위해 다음 python3 스크립트를 작성했습니다 .

#!python3
# file name: letter_image_tool.py

import os, subprocess

"""
command line example to automate
$ jq  '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}
     ]
   }' image_data_annotation.json > image_data_annotation_with_label.json
"""

# define first command line argument
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))

    #jq_command ='jq' + " " +  jq_filter, input_json + ' > ' +  output_json
    jq_command =['jq', jq_filter,  input_json + ' > ' +  output_json]
    print(jq_command)
    subprocess.Popen(jq_command, shell=True)

bash에서 위의 python 스크립트를 실행하면 다음과 같은 결과가 발생합니다.

$ ./letter_image_tool.py
Processing image_data_annotation.json
output file is : image_data_annotation_with_label.json
['jq', '\'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} ] }\'', 'image_data_annotation.json > image_data_annotation_with_label.json']
jq - commandline JSON processor [version 1.6-124-gccc79e5-dirty]

Usage:  jq [options] <jq filter> [file...]
        jq [options] --args <jq filter> [strings...]
        jq [options] --jsonargs <jq filter> [JSON_TEXTS...]

jq is a tool for processing JSON inputs, applying the given filter to
its JSON text inputs and producing the filter's results as JSON on
standard output.

The simplest filter is ., which copies jq's input to its output
unmodified (except for formatting, but note that IEEE754 is used
for number representation internally, with all that that implies).

For more advanced filters see the jq(1) manpage ("man jq")
and/or https://stedolan.github.io/jq

Example:

        $ echo '{"foo": 0}' | jq .
        {
                "foo": 0
        }

For a listing of options, use jq --help.

jq유틸리티 의 첫 번째 인수는 처리하지 않습니다 .

'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}
     ]
   }'

첫 번째 인수는 위의 스 니펫과 같이 작은 따옴표로 묶어야하지만 스크립트가 처리하지 않습니다.

주요 문제는 첫 번째 명령 줄 인수 ( jq_filter위의 Python 스크립트에서)에 사용 된 점, 달러 기호, 작은 따옴표 및 큰 따옴표와 관련이 있다고 생각합니다 . 그러나 나는 bash와 관련된 이런 종류의 복잡한 메타 문자를 다루는 방법을 모릅니다.

위의 문제를 해결하려면 어떻게해야합니까?

읽어 주셔서 감사합니다.

내 솔루션으로 업데이트

jq_filter 정의에 대한 삼중 따옴표 및 다음과 같이 공백으로 분리 된 결합

#!python3
# file name: letter_image_tool.py

import os, subprocess

"""
command line example to automate
$ jq  '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}
     ]
   }' image_data_annotation.json > image_data_annotation_with_label.json
"""

# define first command line argument with triple quotes
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))

    #jq_command ='jq' + " " +  jq_filter, input_json + ' > ' +  output_json
    # jq command composed with space separated join
    jq_command =' '.join['jq', jq_filter,  input_json, ' > ',  output_json]
    print(jq_command)

    # shell keyword argument should be set True
    subprocess.Popen(jq_command, shell=True)

삼중 큰 따옴표를 사용하면 jq_filter는 한 줄로 정의하는 대신 여러 줄로 된 정의를 사용하여 더 쉽게 읽을 수 있습니다.

요한

작은 따옴표가 필요한 이유는 쉘이 인수 확장을 수행하지 못하도록하기 위함입니다. 이는 shell=True. 이것이 설정되지 않으면 쉘은 인수를 건드리지 않으며 인수를 "보호"할 필요가 없습니다.

그러나 셸은 stdout리디렉션 (예 :) 도 담당합니다 [... '>', output_json]. 셸을 사용하지 않고 대신 Python 코드에서 리디렉션을 처리해야합니다. 그러나 이는 인수 stdout=...를에 추가하는 것만 큼 간단 합니다 Popen.

All-in-all 이것은 코드를 다음과 같이 다시 작성할 수 있음을 의미합니다.

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인젝션 공격은 셸에 대한 전체 액세스 권한을 부여 할 수 있으므로 코드에 대한 또 다른 공격 벡터가 열리므로 사용하지 않는 것이 좋습니다 . 또한 셸을 사용하지 않는 또 다른 작은 이점은 추가 셸 프로세스가 필요하지 않기 때문에 생성 된 하위 프로세스의 수가 줄어든다는 것입니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

다른 명령에 대해 작은 따옴표와 큰 따옴표를 포함하는 명령 래핑

분류에서Dev

Ubuntu 명령 줄에서 작은 따옴표 또는 큰 따옴표를 언제 사용해야합니까?

분류에서Dev

작은 따옴표와 따옴표를 사용하지 않는 함수 호출

분류에서Dev

명령을 실행하지만 이미 사용 된 작은 따옴표와 큰 따옴표

분류에서Dev

trap 명령에 사용 된 작은 따옴표와 큰 따옴표의 차이점은 무엇입니까?

분류에서Dev

Bash에서 인용 된 변수로 중첩 된 작은 따옴표와 큰 따옴표가 많은 명령을 실행하는 방법

분류에서Dev

입력 값에 작은 따옴표와 큰 따옴표를 포함하는 에코 문자열

분류에서Dev

문자열이 큰 따옴표 및 작은 따옴표와 함께 작동하지 않습니다.

분류에서Dev

작은 따옴표와 큰 따옴표를 모두 사용하여 문자열에서 명령 실행

분류에서Dev

큰 따옴표와 함께 sed 사용

분류에서Dev

이 Perl 솔루션을 수정하여 포함 된 큰 따옴표를 작은 따옴표로 대체하려면 어떻게해야합니까?

분류에서Dev

이 Perl 솔루션을 수정하여 포함 된 큰 따옴표를 작은 따옴표로 대체하려면 어떻게해야합니까?

분류에서Dev

자바 스크립트 : 왜 작은 따옴표와 큰 따옴표가 여전히 함께 존재합니까?

분류에서Dev

string.IndexOf () 함수의 큰 따옴표 안에 큰 따옴표를 넣는 방법은 무엇입니까?

분류에서Dev

PHP DOMXPath는 큰 따옴표와 함께 작동합니다.

분류에서Dev

작은 따옴표와 큰 따옴표가 모두있는 표현식을 어떻게 에코합니까?

분류에서Dev

큰 따옴표, 작은 따옴표를 혼합하는 방법

분류에서Dev

변수 및 작은 따옴표와 함께 subprocess.call 사용

분류에서Dev

작은 따옴표 / 큰 따옴표와 괄호를 확인하는 정규식?

분류에서Dev

sed를 사용하여 따옴표와 작은 따옴표가 포함 된 텍스트를 바꿉니다.

분류에서Dev

여러 변수와 함께 console.log에서 작은 따옴표를 사용하는 방법

분류에서Dev

bash에서 따옴표가 포함 된 변수를 사용하여 명령을 실행하는 방법은 무엇입니까?

분류에서Dev

자바 스크립트에서 작은 따옴표와 큰 따옴표를 사용하는 방법

분류에서Dev

큰 따옴표 나 작은 따옴표를 사용하지 않고 특정 문자열을 인쇄하는 방법은 무엇입니까?

분류에서Dev

vim-작은 따옴표와 큰 따옴표가 섞인 파일 이름을 이스케이프하는 방법은 무엇입니까?

분류에서Dev

작은 따옴표로 묶인 sed 명령은 작동하지만 큰 따옴표를 사용하지 않습니다.

분류에서Dev

따옴표가 포함 된 인수와 함께 watch 명령 사용

분류에서Dev

따옴표가 포함 된 인수와 함께 watch 명령 사용

분류에서Dev

작은 따옴표와 큰 따옴표가 모두 이미 사용 된 경우 따옴표로 묶는 방법은 무엇입니까?

Related 관련 기사

  1. 1

    다른 명령에 대해 작은 따옴표와 큰 따옴표를 포함하는 명령 래핑

  2. 2

    Ubuntu 명령 줄에서 작은 따옴표 또는 큰 따옴표를 언제 사용해야합니까?

  3. 3

    작은 따옴표와 따옴표를 사용하지 않는 함수 호출

  4. 4

    명령을 실행하지만 이미 사용 된 작은 따옴표와 큰 따옴표

  5. 5

    trap 명령에 사용 된 작은 따옴표와 큰 따옴표의 차이점은 무엇입니까?

  6. 6

    Bash에서 인용 된 변수로 중첩 된 작은 따옴표와 큰 따옴표가 많은 명령을 실행하는 방법

  7. 7

    입력 값에 작은 따옴표와 큰 따옴표를 포함하는 에코 문자열

  8. 8

    문자열이 큰 따옴표 및 작은 따옴표와 함께 작동하지 않습니다.

  9. 9

    작은 따옴표와 큰 따옴표를 모두 사용하여 문자열에서 명령 실행

  10. 10

    큰 따옴표와 함께 sed 사용

  11. 11

    이 Perl 솔루션을 수정하여 포함 된 큰 따옴표를 작은 따옴표로 대체하려면 어떻게해야합니까?

  12. 12

    이 Perl 솔루션을 수정하여 포함 된 큰 따옴표를 작은 따옴표로 대체하려면 어떻게해야합니까?

  13. 13

    자바 스크립트 : 왜 작은 따옴표와 큰 따옴표가 여전히 함께 존재합니까?

  14. 14

    string.IndexOf () 함수의 큰 따옴표 안에 큰 따옴표를 넣는 방법은 무엇입니까?

  15. 15

    PHP DOMXPath는 큰 따옴표와 함께 작동합니다.

  16. 16

    작은 따옴표와 큰 따옴표가 모두있는 표현식을 어떻게 에코합니까?

  17. 17

    큰 따옴표, 작은 따옴표를 혼합하는 방법

  18. 18

    변수 및 작은 따옴표와 함께 subprocess.call 사용

  19. 19

    작은 따옴표 / 큰 따옴표와 괄호를 확인하는 정규식?

  20. 20

    sed를 사용하여 따옴표와 작은 따옴표가 포함 된 텍스트를 바꿉니다.

  21. 21

    여러 변수와 함께 console.log에서 작은 따옴표를 사용하는 방법

  22. 22

    bash에서 따옴표가 포함 된 변수를 사용하여 명령을 실행하는 방법은 무엇입니까?

  23. 23

    자바 스크립트에서 작은 따옴표와 큰 따옴표를 사용하는 방법

  24. 24

    큰 따옴표 나 작은 따옴표를 사용하지 않고 특정 문자열을 인쇄하는 방법은 무엇입니까?

  25. 25

    vim-작은 따옴표와 큰 따옴표가 섞인 파일 이름을 이스케이프하는 방법은 무엇입니까?

  26. 26

    작은 따옴표로 묶인 sed 명령은 작동하지만 큰 따옴표를 사용하지 않습니다.

  27. 27

    따옴표가 포함 된 인수와 함께 watch 명령 사용

  28. 28

    따옴표가 포함 된 인수와 함께 watch 명령 사용

  29. 29

    작은 따옴표와 큰 따옴표가 모두 이미 사용 된 경우 따옴표로 묶는 방법은 무엇입니까?

뜨겁다태그

보관