json에서 매개변수를 구문 분석할 수 없습니다.

json에서 매개변수를 구문 분석할 수 없습니다.

API에서 일부 데이터를 검색하기 위해 스크립트( edm.ksh)에서 컬 명령을 사용하고 있는데 JSON 형식의 비밀번호가 필요합니다 {"password":"myPassword"}. 예를 들어 myPassword하드코딩되지 않고 edm.ksh내가 추출한 구성 파일에서 가져온 것입니다. 변하기 쉬운.

edm.ksh:

#! /usr/bin/ksh
export PASSWORD=$(grep PASSWORD /home/dummy/password.txt | awk -F " " '{print $2}')
export PASSWORD_TXT=$(echo -e "'"'{"password":"'${PASSWORD}'"}'"'")
curl -k -X POST -d $PASSWORD_TXT ${LDAP_URL} > ${TEMP_DIR}/token.dat
$ cat /home/dummy/password.txt
PASSWORD myPassword

스크립트를 실행하면 $PASSWORD_TXT가 구문 분석될 것으로 예상하는데 스크립트로 출력 '{"password":"myPassword"}'됩니다 . $'\'{"password":"myPassword"}\''명령줄에서는 완벽하게 구문 분석하지만 스크립트에서는 구문 분석하지 않습니다. 이스케이프 문자를 사용하여 올바른 json 구문 분석을 수행하는 방법에 대해 도움을 줄 수 있는 사람이 있습니까?

나는 심지어 다음과 같은 것을 시도했다

curl -k -X POST -d  '{"password":"${PASSWORD_TXT}"}' ${LDAP_URL} > ${TEMP_DIR}/token.dat

그러나 변수는 JSON에서 구문 분석되지 않습니다.

이 문제에 대한 단서를 얻을 수 있다면 매우 감사하겠습니다.

미리 감사드립니다!

답변1

표시한 코드에는 몇 가지 문제가 있습니다.

  • 파일에서 비밀번호를 읽는 방식에서는 비밀번호에 공백이나 기타 공백이 포함되어 있지 않다고 가정합니다.
  • 비밀번호가 포함된 JSON 문서는 비밀번호 문자열을 JSON으로 인코딩하지 않습니다. 이는 비밀번호에 허용되는 문자를 제한한다는 의미입니다.
  • 여러 셸 변수는 작은따옴표(해당 값으로 확장되지 않음을 의미) 또는 따옴표가 없습니다(셸이 해당 값을 확장하고 공백으로 분할하고 확장 비트 이름 와일드카드에서 파일을 실행함을 의미).

비밀번호가 PASSWORDstring 으로 시작하는 줄의 첫 번째 공백 뒤의 파일 줄의 나머지 부분 이라고 가정하면 password.txt다음을 사용하여 비밀번호를 읽을 수 있습니다.

password=$( sed -e '/^PASSWORD /!d' -e 's///' -e q <password.txt )

이렇게 하면 으로 시작하지 않는 모든 줄이 삭제되고 PASSWORD, 이를 포함하는 첫 번째 줄에서 접두사 문자열이 제거되며, 결과가 인쇄되고 파일 처리가 중지됩니다. 이 password변수는 내보낼 필요가 없습니다.

예:

$ cat password.txt
PASSWORD this is "the password"
$ password=$( sed -e '/^PASSWORD /!d' -e 's///' -e q <password.txt )
$ printf 'Password: %s\n' "$password"
Password: this is "the password"

이 방법으로 비밀번호를 읽으면 비밀번호 값의 후행 공백이 제거됩니다(이는 명령 대체 때문입니다).

password다음 명령을 사용하여 읽기 비밀번호 문자열을 키 값으로 포함하는 JSON 문서를 생성 할 수 있습니다.JSON 처리 도구jq:

json_payload=$( jq -n -c --arg password "$password" '$ARGS.named' )

또는 다음을 사용하십시오.명령줄 JSON 작성 도구jo,

json_payload=$( jo password="$password" )

또는 다음을 사용하십시오.Miller는 일반적인 구조화된 문서 형식 작업을 위해 선택한 도구입니다.,

json_payload=$( mlr -n --ojsonl put -s password="$password" 'end { emit @password }' )

또는 Python을 사용하여

json_payload=$( python -c 'import sys, json; print(json.dumps({"password": sys.argv[1]}))' "$password" )

또는 Perl을 사용하여

json_payload=$( perl -MJSON -e 'print encode_json({"password" => $ARGV[0]});' "$password" )

비밀번호에 포함된 문자에 관계없이 문자열은 유효한 JSON 인코딩 문자열로 인코딩되고 passwordJSON 개체에 키 값으로 삽입됩니다. 이 쉘 변수도 내보낼 필요가 없습니다.

예:

$ printf 'Password: %s\n' "$password"
Password: this is "the password"
$ json_payload=$( jq -n -c --arg password "$password" '$ARGS.named' )
$ printf 'JSON document: %s\n' "$json_payload"
JSON document: {"password":"this is \"the password\""}

curlAPI 엔드포인트를 호출 하려면 다음을 사용하세요 .

curl --silent \
    --request POST \
    --header 'Content-Type: application/json' \
    --data "$json_payload" "$api_endpoint_url" >output

여기에 제공하는 코드의 모든 참조는 우연이거나 중복되지 않습니다. 쉘이 변수의 문자열을 분할하거나 문자를 특별한 방식으로 해석하지 않도록 모든 확장에 큰따옴표를 사용해야 합니다. 예를 들어 참조하십시오.언제 큰따옴표가 필요합니까?


위의 모든 항목을 스크립트에 수집하고, 오류 처리를 수행하지 않고, json_payload쉘 변수를 제거하고(필요하지 않은 경우) 사용합니다.바로가기 --json옵션그리고 curl:

#!/bin/sh

api_endpoint_url='some URL here'

password=$( sed -e '/^PASSWORD /!d' -e 's///' -e q <password.txt )

jq -n -c --arg password "$password" '$ARGS.named' |
curl --silent --json @- "$api_endpoint_url" >output

관련 정보