Bash 변수를 사용하여 JSON 문자열 구축
이러한 bash 변수를 JSON 문자열로 읽어야 하는데 bash에 익숙하지 않습니다.어떤 도움이라도 감사합니다.
#!/bin/sh
BUCKET_NAME=testbucket
OBJECT_NAME=testworkflow-2.0.1.jar
TARGET_LOCATION=/opt/test/testworkflow-2.0.1.jar
JSON_STRING='{"bucketname":"$BUCKET_NAME"","objectname":"$OBJECT_NAME","targetlocation":"$TARGET_LOCATION"}'
echo $JSON_STRING
하다, , 하다, 라고 하는 프로그램을 사용하는 것이 좋습니다.jqJSON을 생성하기 위해 변수의 내용이 올바르게 이스케이프되어 있는지 미리 알 수 없는 경우.JSON을 사용하다
BUCKET_NAME=testbucket
OBJECT_NAME=testworkflow-2.0.1.jar
TARGET_LOCATION=/opt/test/testworkflow-2.0.1.jar
JSON_STRING=$( jq -n \
--arg bn "$BUCKET_NAME" \
--arg on "$OBJECT_NAME" \
--arg tl "$TARGET_LOCATION" \
'{bucketname: $bn, objectname: $on, targetlocation: $tl}' )
하시면 됩니다.printf:
JSON_FMT='{"bucketname":"%s","objectname":"%s","targetlocation":"%s"}\n'
printf "$JSON_FMT" "$BUCKET_NAME" "$OBJECT_NAME" "$TARGET_LOCATION"
훨씬 명료하고 심플한
가능성:
#!/bin/bash
BUCKET_NAME="testbucket"
OBJECT_NAME="testworkflow-2.0.1.jar"
TARGET_LOCATION="/opt/test/testworkflow-2.0.1.jar
# one line
JSON_STRING='{"bucketname":"'"$BUCKET_NAME"'","objectname":"'"$OBJECT_NAME"'","targetlocation":"'"$TARGET_LOCATION"'"}'
# multi-line
JSON_STRING="{
\"bucketname\":\"${BUCKET_NAME}\",
\"objectname\":\"${OBJECT_NAME}\",
\"targetlocation\":\"${TARGET_LOCATION}\"
}"
# [optional] validate the string is valid json
echo "${JSON_STRING}" | jq
Chepner의 답변 외에 다음과 같은 간단한 레시피로 arg에서 객체를 완전히 구성할 수도 있습니다.
BUCKET_NAME=testbucket
OBJECT_NAME=testworkflow-2.0.1.jar
TARGET_LOCATION=/opt/test/testworkflow-2.0.1.jar
JSON_STRING=$(jq -n \
--arg bucketname "$BUCKET_NAME" \
--arg objectname "$OBJECT_NAME" \
--arg targetlocation "$TARGET_LOCATION" \
'$ARGS.named')
설명:
--null-input | -n판독 입력을 사용할 수 없습니다.부터: man ★★★★★★★★★★★★★★★★★★★」Don't read any input at all! Instead, the filter is run once using null as the input. This is useful when using jq as a simple calculator or to construct JSON data from scratch.--arg name value는 사전에 변수로서 값을 합니다.예를 들어, 「 」는 「 」의 「 에는 「 」가 정의되어 있습니다.value는, 「이렇게 하다」로 사용할 수 .$name된 모든 명된음음음음음음음음음음음음음음 are are are are are are are로 사용할 수 있습니다.$ARGS.named
의 of의 $ARGS.named대상입니다.jq그대로 출력할 수 있습니다.
첫째, ALL_CAPS_VARNAMES를 사용하지 마십시오.PATH와 같은 중요한 셸 변수를 실수로 덮어쓰기가 너무 쉽습니다.
셸 스트링에 작은 따옴표와 큰 따옴표를 섞는 것은 번거로울 수 있습니다.우,, 는는을 사용합니다.printf:
bucket_name=testbucket
object_name=testworkflow-2.0.1.jar
target_location=/opt/test/testworkflow-2.0.1.jar
template='{"bucketname":"%s","objectname":"%s","targetlocation":"%s"}'
json_string=$(printf "$template" "$BUCKET_NAME" "$OBJECT_NAME" "$TARGET_LOCATION")
echo "$json_string"
숙제에 대해서는, 이 페이지를 주의 깊게 읽어 주세요.bash/POSIX 쉘에서 변수의 따옴표를 잊어버렸을 경우의 보안상의 영향
문자열 연결을 사용하여 JSON을 작성하는 방법에 대한 주의: 엣지 케이스가 있습니다.예를 들어 이중 따옴표가 포함된 문자열이 있으면 JSON을 끊을 수 있습니다.
$ bucket_name='a "string with quotes"'
$ printf '{"bucket":"%s"}\n' "$bucket_name"
{"bucket":"a "string with quotes""}
bash를 사용하면 이 작업을 더 안전하게 수행할 수 있습니다. 이 문자열의 큰따옴표는 이스케이프해야 합니다.
$ printf '{"bucket":"%s"}\n' "${bucket_name//\"/\\\"}"
{"bucket":"a \"string with quotes\""}
명령어 요청에서 json 문자열을 처리할 수 있는 모든 방법을 강구해야 했습니다. 작은따옴표를 잘못 사용하면 실패할 수 있는 이유를 다음 코드를 참조하십시오.
# Create Release and Tag commit in Github repository
# returns string with in-place substituted variables
json=$(cat <<-END
{
"tag_name": "${version}",
"target_commitish": "${branch}",
"name": "${title}",
"body": "${notes}",
"draft": ${is_draft},
"prerelease": ${is_prerelease}
}
END
)
# returns raw string without any substitutions
# single or double quoted delimiter - check HEREDOC specs
json=$(cat <<-!"END" # or 'END'
{
"tag_name": "${version}",
"target_commitish": "${branch}",
"name": "${title}",
"body": "${notes}",
"draft": ${is_draft},
"prerelease": ${is_prerelease}
}
END
)
# prints fully formatted string with substituted variables as follows:
echo "${json}"
{
"tag_name" : "My_tag",
"target_commitish":"My_branch"
....
}
주 1: 작은따옴표와 큰따옴표 사용
# enclosing in single quotes means no variable substitution
# (treats everything as raw char literals)
echo '${json}'
${json}
echo '"${json}"'
"${json}"
# enclosing in single quotes and outer double quotes causes
# variable expansion surrounded by single quotes(treated as raw char literals).
echo "'${json}'"
'{
"tag_name" : "My_tag",
"target_commitish":"My_branch"
....
}'
주 2: 회선 터미네이터에 대한 주의
- 은 LF json " " " " LF " " " " " 의 회선 .
\n - return (반환)
\rCRLF(CRLF)가 포함됩니다).\r\n) - 사용(표준)
tr할 수 .
# following code serializes json and removes any line terminators
# in substituted value/object variables too
json=$(echo "$json" | tr -d '\n' | tr -d '\r' )
# string enclosed in single quotes are still raw literals
echo '${json}'
${json}
echo '"${json}"'
"${json}"
# After CRLF/LF are removed
echo "'${json}'"
'{ "tag_name" : "My_tag", "target_commitish":"My_branch" .... }'
주 3: 포맷
- json 을 조작하면서 json의 할 수 .
'★★★★★★★★★★★★★★★★★」"다음과 같이 외부 이중 따옴표를 사용하여 일부 원시 리터럴을 보호하고 하위 구성/문자열 보간법을 사용하는 경우:
# mixing ' and "
username=admin
password=pass
echo "$username:$password"
admin:pass
echo "$username"':'"$password"
admin:pass
echo "$username"'[${delimiter}]'"$password"
admin[${delimiter}]pass
주 4: 명령어에서의 사용
- 컬 은 이미 컬 요청을 합니다.
\n, serialize serialize json, json)
response=$(curl -i \
--user ${username}:${api_token} \
-X POST \
-H 'Accept: application/vnd.github.v3+json' \
-d "$json" \
"https://api.github.com/repos/${username}/${repository}/releases" \
--output /dev/null \
--write-out "%{http_code}" \
--silent
)
따라서 명령 변수에 사용할 때는 사용하기 전에 형식이 올바른지 확인하십시오.
정의되지 않은 변수 또는 빈 변수에 매핑된 멤버를 생략해야 하는 JSON 표현을 작성해야 할 경우 도움이 됩니다.
#!/bin/bash
BUCKET_NAME=testbucket
OBJECT_NAME=""
JO_OPTS=()
if [[ ! "${BUCKET_NAME}x" = "x" ]] ; then
JO_OPTS+=("bucketname=${BUCKET_NAME}")
fi
if [[ ! "${OBJECT_NAME}x" = "x" ]] ; then
JO_OPTS+=("objectname=${OBJECT_NAME}")
fi
if [[ ! "${TARGET_LOCATION}x" = "x" ]] ; then
JO_OPTS+=("targetlocation=${TARGET_LOCATION}")
fi
jo "${JO_OPTS[@]}"
다음과 (''이 없는 것에 해 주세요.objectname ★★★★★★★★★★★★★★★★★」targetlocation( ) :
{"bucketname":"testbucket"}
다음 방법으로 실행할 수 있습니다.
JSON_STRING='{"bucketname":"'$BUCKET_NAME'","objectname":"'$OBJECT_NAME'","targetlocation":"'$TARGET_LOCATION'"}'
★★★의 Node.js개발자 또는 노드 환경이 설치되어 있는 경우 다음을 시도할 수 있습니다.
JSON_STRING=$(node -e "console.log(JSON.stringify({bucketname: $BUCKET_NAME, objectname: $OBJECT_NAME, targetlocation: $TARGET_LOCATION}))")
이 방법의 장점은 매우 복잡한 JSON 객체(개체에 배열이 포함되어 있거나 문자열 대신 int 값이 필요한 경우)를 비활성 json 오류에 대해 걱정하지 않고 쉽게 JSON 문자열로 변환할 수 있다는 것입니다.
점면면면면면면 on on on 에 의존해서Node.js★★★★★★ 。
이러한 솔루션은 조금 늦게 제공되지만, 이전 제안보다 본질적으로 더 단순하다고 생각합니다(견적과 회피의 복잡함 회피).
BUCKET_NAME=testbucket
OBJECT_NAME=testworkflow-2.0.1.jar
TARGET_LOCATION=/opt/test/testworkflow-2.0.1.jar
# Initial unsuccessful solution
JSON_STRING='{"bucketname":"$BUCKET_NAME","objectname":"$OBJECT_NAME","targetlocation":"$TARGET_LOCATION"}'
echo $JSON_STRING
# If your substitution variables have NO whitespace this is sufficient
JSON_STRING=$(tr -d [:space:] <<JSON
{"bucketname":"$BUCKET_NAME","objectname":"$OBJECT_NAME","targetlocation":"$TARGET_LOCATION"}
JSON
)
echo $JSON_STRING
# If your substitution variables are more general and maybe have whitespace this works
JSON_STRING=$(jq -c . <<JSON
{"bucketname":"$BUCKET_NAME","objectname":"$OBJECT_NAME","targetlocation":"$TARGET_LOCATION"}
JSON
)
echo $JSON_STRING
#... A change in layout could also make it more maintainable
JSON_STRING=$(jq -c . <<JSON
{
"bucketname" : "$BUCKET_NAME",
"objectname" : "$OBJECT_NAME",
"targetlocation" : "$TARGET_LOCATION"
}
JSON
)
echo $JSON_STRING
노드를 사용하여 Hao의 답변을 기반으로 한다.JS: 회선을 사용할 수 있습니다.-p하여 ""를 사용해야 번거로움을 덜어집니다.console.log.
JSON_STRING=$(node -pe "
JSON.stringify({
bucketname: process.env.BUCKET_NAME,
objectname: process.env.OBJECT_NAME,
targetlocation: process.env.TARGET_LOCATION
});
")
불편한 점은 변수를 미리 내보내야 한다는 것입니다.
export BUCKET_NAME=testbucket
# etc.
왜'를 사용하는가?라고 생각할 수 있습니다.라고 생각할 수 있습니다.process.env하고, 「따옴표」를 붙이는 은 어떨까요bucketname: '$BUCKET_NAME',bash bash 、 입 bash 、 bash bash 、 bash bash?그 이유는 를 사용하는 것이process.env더 안전하다 - 당신이 그 내용을 통제할 수 없다면$TARGET_LOCATION할 수 를 들어, "JavaScript"의 작은 따옴표를 것).$TARGET_LOCATION의 내용은 「」로 할 수 .'}); /* Here I can run commands to delete files! */; console.log({'a': 'b★★★★★★★★★★★★★★★★★★★.process.env입력물을 청소합니다.
하면 .envsubst:
export VAR="some_value_here"
echo '{"test":"$VAR"}' | envsubst > json.json
또, 「스위치」파일이 되는 경우도 있습니다.
//json.template
{"var": "$VALUE", "another_var":"$ANOTHER_VALUE"}
그러면 다음 작업을 수행할 수 있습니다.
export VALUE="some_value_here"
export ANOTHER_VALUE="something_else"
cat json.template | envsubst > misha.json
Bash는 단일 따옴표 문자열에 변수를 삽입하지 않습니다.변수를 가져오려면 bash가 큰따옴표로 묶인 문자열이 필요합니다.JSON에는 큰따옴표를 사용하여 JSON 문자열 내의 큰따옴표를 이스케이프해야 합니다.예:
#!/bin/sh
BUCKET_NAME=testbucket
OBJECT_NAME=testworkflow-2.0.1.jar
TARGET_LOCATION=/opt/test/testworkflow-2.0.1.jar
JSON_STRING="{\"bucketname\":\"$BUCKET_NAME\",\"objectname\":\"$OBJECT_NAME\",\"targetlocation\":\"$TARGET_LOCATION\"}"
echo $JSON_STRING
node.minimist 가 글로벌하게 설치되어 있는 경우:
jc() {
node -p "JSON.stringify(require('minimist')(process.argv), (k,v) => k=='_'?undefined:v)" -- "$@"
}
jc --key1 foo --number 12 --boolean \
--under_score 'abc def' --'white space' ' '
# {"key1":"foo","number":12,"boolean":true,"under_score":"abc def","white space":" "}
컬로 올릴 수도 있고 뭐 그런 것도 있어요.
curl --data "$(jc --type message --value 'hello world!')" \
--header 'content-type: application/json' \
http://server.ip/api/endpoint
미니미스트가 도트를 해석하는 것에 주의해 주세요.
jc --m.room.member @gholk:ccns.io
# {"m":{"room":{"member":"@gholk:ccns.io"}}}
AWS Macie 구성에 사용:
JSON_CONFIG=$( jq -n \
--arg bucket_name "$BUCKET_NAME" \
--arg kms_key_arn "$KMS_KEY_ARN" \
'{"s3Destination":{"bucketName":$bucket_name,"kmsKeyArn":$kms_key_arn}}'
)
aws macie2 put-classification-export-configuration --configuration "$JSON_CONFIG"
임의의 입력을 사용하여 bash에서 JSON을 구축하는 일반적인 경우 이전 응답의 많은 수(투표율이 높은 응답도)jq) 변수가 다음을 포함하는 경우는 생략합니다."큰따옴표 또는\nnewline excape string. 입력의 복잡한 스트링을 연결해야 합니다.
「」를 사용하고 jq 가 있다printf %b으로 ""를 .\n 줄바꿈으로 하면 jq를 사용할 수 .\n(가 아니라) \\n.
nodejs 버전에서는 javascript/nodejs를 잘 알고 있다면 쉽게 이해할 수 있습니다.
TITLE='Title'
AUTHOR='Bob'
JSON=$( TITLE="$TITLE" AUTHOR="$AUTHOR" node -p 'JSON.stringify( {"message": `Title: ${process.env.TITLE}\n\nAuthor: ${process.env.AUTHOR}`} )' )
장황한 process.env.그러나 셸에서 변수를 적절하게 전달하고 안전한 방법으로 내부(nodej) 백틱을 포맷할 수 있습니다.
출력은 다음과 같습니다.
printf "%s\n" "$JSON"
{"message":"Title: Title\n\nAuthor: Bob"}
(주의: 항상 use를 사용하는 변수가 있고 출력은 플랫폼에 의존하지 않는 경우!자세한 내용은 여기를 참조해 주세요.
와 비슷한 점jq
TITLE='Title'
AUTHOR='Bob'
MESSAGE="Title: ${TITLE}\n\nAuthor: ${AUTHOR}"
MESSAGE_ESCAPED_FOR_JQ=$(printf %b "${MESSAGE}")
JSON=$( jq '{"message": $jq_msg}' --arg jq_msg "$MESSAGE_ESCAPED_FOR_JQ" --null-input --compact-output --raw-output --monochrome-output )
는 마지막 2개의 , (2개의 파라미터가 있다)를 실행할 때 입니다.다만, 이 파라미터들을 추가한 것만으로, 실행시의 출력이 같게 됩니다.jq명령어를 최상위 셸에 액세스 할 수 있습니다.
이렇게 전화를 걸어 JSON을 출력할 수 있습니다.
#!/bin/sh
BUCKET_NAME=testbucket
OBJECT_NAME=testworkflow-2.0.1.jar
TARGET_LOCATION=/opt/test/testworkflow-2.0.1.jar
echo '{ "bucketName": "'"$BUCKET_NAME"'", "objectName": "'"$OBJECT_NAME"'", "targetLocation": "'"$TARGET_LOCATION"'" }'
또는
JSON_STRING='{ "bucketName": "'"$BUCKET_NAME"'", "objectName": "'"$OBJECT_NAME"'", "targetLocation": "'"$TARGET_LOCATION"'" }'
echo $JOSN_STRING
언급URL : https://stackoverflow.com/questions/48470049/build-a-json-string-with-bash-variables
'programing' 카테고리의 다른 글
| 현지화를 위한 각도 js 지원 (0) | 2023.03.10 |
|---|---|
| Jquery 및 HTML FormData는 "Uncatched TypeError:부정한 호출" (0) | 2023.03.10 |
| AngularJS/Javascript 날짜 문자열에서 날짜 개체로 변환 (0) | 2023.03.10 |
| 스크립트 실행을 거부했습니다. 엄격한 MIME 유형 검사가 사용되도록 설정되었습니까? (0) | 2023.03.10 |
| cPanel에서 최대 업로드 크기를 늘리는 방법 (0) | 2023.03.10 |