null
文字列または文字列の配列である可能性のある変数を繰り返したいと思います。
ZEIT_DEPLOYMENT_ALIASES=null
またはZEIT_DEPLOYMENT_ALIASES=['domain.sh]
私はbashの初心者で、読みました。bashは空でない限りファイルのリストを繰り返します。しかし、理解できません。
私は2つの異なるアプローチを試しました。
値はZEIT_DEPLOYMENT_ALIASES
、実際にjq
JSONを読み取るライブラリから取得されます。
ZEIT_DEPLOYMENT_ALIASES=$(cat now.$CUSTOMER_REF_TO_DEPLOY.staging.json | jq --raw-output '.alias')
方法1
ZEIT_DEPLOYMENT_ALIASES=['test.sh']
# Check if there are no aliases configured
if [ -z "$ZEIT_DEPLOYMENT_ALIASES" ]
then
ZEIT_DEPLOYMENT_ALIASES_COUNT=${#ZEIT_DEPLOYMENT_ALIASES[@]}
echo "$ZEIT_DEPLOYMENT_ALIASES_COUNT alias(es) found. Aliasing them now..."
# For each alias configured, then alias it to the deployed domain
for DEPLOYMENT_ALIAS in "${ZEIT_DEPLOYMENT_ALIASES_COUNT[@]}"
do
echo "npx now alias "$ZEIT_DEPLOYMENT_URL $DEPLOYMENT_ALIAS
npx now alias $ZEIT_DEPLOYMENT_URL $DEPLOYMENT_ALIAS --token $ZEIT_TOKEN || echo "Aliasing failed for '$DEPLOYMENT_ALIAS', but the build will continue regardless."
done
else
# $ZEIT_DEPLOYMENT_ALIASES is null, this happens when it was not defined in the now.json file
echo "There are no more aliases to configure. You can add more aliases from your now.json 'alias' property. See https://vercel.com/docs/configuration?query=alias%20domain#project/alias"
echo "$ZEIT_DEPLOYMENT_ALIASES"
fi
しかし、これさえ規約ZEIT_DEPLOYMENT_ALIASES=['something']
に入らない。then
方法2
ZEIT_DEPLOYMENT_ALIASES=['test.sh']
echo "Alias(es) for current project:" $ZEIT_DEPLOYMENT_ALIASES
for DEPLOYMENT_ALIAS in $ZEIT_DEPLOYMENT_ALIASES; do
[ -z "$DEPLOYMENT_ALIAS" ] || continue
echo "npx now alias "$ZEIT_DEPLOYMENT_URL $DEPLOYMENT_ALIAS
npx now alias $ZEIT_DEPLOYMENT_URL $DEPLOYMENT_ALIAS --token $ZEIT_TOKEN || echo "Aliasing failed for '$DEPLOYMENT_ALIAS', but the build will continue regardless."
done
繰り返しますが、[ -z "$DEPLOYMENT_ALIAS" ]
常にtrue
。
必要に応じて遊び場は次のとおりです。
ベストアンサー1
このファイルが与えられたら:
$ cat test.json
{"alias": ["foo", "bar"], "whatever": "xyzzy"}
少なくとも私のバージョンはjq
この出力を提供します。jq --raw-output '.alias[]' < test.json
$ jq --raw-output '.alias[]' < test.json
foo
bar
つまり、項目が異なる行にあります。これを使用して項目を区別できるため、これは重要です。たとえば、readarray
<(...)
プロセスの交換これにより、コマンドの出力がファイルのように使用できるようになり、< <(...)
標準入力で使用できるようになります。実際には、パイプがサブシェルを実行していることを除いて、パイプと少し似ているため、パイプの後に読み取った値は使用できません。 )
#!/bin/bash
readarray -t entries < <(jq '.alias[]' < test.json)
if [ "${#entries[@]}" = 0 ]; then
echo empty array...
fi
# this will not do anything if the array is empty
for entry in "${entries[@]}"; do
echo "processing entry $entry..."
done
alias
不足している可能性のあるフィールドを処理するには、代わりに.alias[]?
inを使用してくださいjq
。ただし、これは{"alias": "foo"}
配列ではなく文字列値(たとえば)をnullとして扱うため、可能であれば他の操作を実行する必要があります。
また、項目に改行文字が含まれている場合はそのまま印刷されるため、--raw-output
改行文字を含む項目は、複数の個別項目であるかのように複数行にわたって分割されて表示されます。
あるいは、プロセスの置き換えは必要ないので、Bashだけでなく標準シェルでも機能する必要があります。
#!/bin/sh
jq --raw-output '.alias[]' < json.txt |
(
any=
while IFS= read -r line; do
echo "doing something with '$line'..."
any=1
done
if [ "$any" != 1 ]; then
echo "empty input..."
fi
)
バラより私の変数が1つの「読み込み中」ループではローカルですが、一見似ている他のループではローカルではないのはなぜですか?かっこが必要な理由について。
今コードについて:
ZEIT_DEPLOYMENT_ALIASES=['test.sh']
これにより、文字列が[test.sh]
変数に割り当てられます。これは["test.sh"]
、から取得した文字列の割り当てとは異なりますjq
。これは、シェルがユーザーが提供した引用符を処理するためです。コマンド置換の出力に基づいて同様に処理されません。これは配列ではなく単一のスカラー変数でもあります。
if [ -z "$ZEIT_DEPLOYMENT_ALIASES" ]
これは文字列が空の文字列であるかどうかをテストします。これはおそらく意図したものではありません。とにかく、jq
与える.alias
ことができますひも null
、これは空の文字列とは異なります。
${#ZEIT_DEPLOYMENT_ALIASES[@]}
1
これは配列ではないため、常にそうです。同じ理由で、
for
ループは必要に応じて機能しません。
BashはJSON自体を処理しません。コマンド置換から文字列を取得すると、["foo", "bar"]
これはJSONです。ひも。個々のアイテムに直接分割する必要があります...