Bashは配列を繰り返し、空であるかどうかを検出します。

Bashは配列を繰り返し、空であるかどうかを検出します。

null文字列または文字列の配列である可能性のある変数を繰り返したいと思います。

ZEIT_DEPLOYMENT_ALIASES=nullまたはZEIT_DEPLOYMENT_ALIASES=['domain.sh]

私はbashの初心者で、読みました。bashは空でない限りファイルのリストを繰り返します。しかし、理解できません。

私は2つの異なるアプローチを試しました。

値はZEIT_DEPLOYMENT_ALIASES、実際にjqJSONを読み取るライブラリから取得されます。

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. https://www.jdoodle.com/iembed/v0/3bs
  2. https://www.jdoodle.com/iembed/v0/3bo

ベストアンサー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です。ひも。個々のアイテムに直接分割する必要があります...

おすすめ記事