Построить строку JSON с переменными Bash

Мне нужно прочитать эти переменные 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 

Ответ 1

Вам лучше использовать такую программу, как jq для генерации JSON, если вы не знаете заранее, если содержимое переменных правильно экранировано для включения в JSON. В противном случае вы просто закончите с недействительным 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}' )

Ответ 2

Вы можете использовать printf:

JSON_FMT='{"bucketname":"%s","objectname":"%s","targetlocation":"%s"}\n'
printf "$JSON_FMT" "$BUCKET_NAME" "$OBJECT_NAME" "$TARGET_LOCATION"

гораздо яснее и проще

Ответ 3

Возможность:

JSON_STRING='{"bucketname":"'"$BUCKET_NAME"'","objectname":"'"$OBJECT_NAME"'","targetlocation":"'"$TARGET_LOCATION"'"}'

Ответ 4

Во-первых, не используйте 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\""}

Ответ 5

Если вам нужно создать представление JSON, в котором члены, отображаемые в неопределенные или пустые переменные, должны быть пропущены, тогда jo может помочь.

#!/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[@]}"

Ответ 6

Джо был сделан именно для вашего случая использования

Ответ 7

можно сделать следующим образом:

JSON_STRING='{"bucketname":"'$BUCKET_NAME'","objectname":"'$OBJECT_NAME'","targetlocation":"'$TARGET_LOCATION'"}'