![Bash는 배열을 반복하고 비어 있는지 감지합니다.](https://linux55.com/image/182088/Bash%EB%8A%94%20%EB%B0%B0%EC%97%B4%EC%9D%84%20%EB%B0%98%EB%B3%B5%ED%95%98%EA%B3%A0%20%EB%B9%84%EC%96%B4%20%EC%9E%88%EB%8A%94%EC%A7%80%20%EA%B0%90%EC%A7%80%ED%95%A9%EB%8B%88%EB%8B%A4..png)
null
문자열 또는 문자열 배열일 수 있는 변수를 반복하려고 합니다 .
ZEIT_DEPLOYMENT_ALIASES=null
또는ZEIT_DEPLOYMENT_ALIASES=['domain.sh]
나는 bash의 초보자이고 읽었습니다.bash는 비어 있지 않은 한 파일 목록을 반복합니다.하지만 이해가 안 돼요.
나는 두 가지 다른 접근 방식을 시도했습니다.
값은 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
)
바라보다내 변수가 하나의 "읽는 동안" 루프에서는 로컬이지만 겉보기에 유사한 다른 루프에서는 로컬이 아닌 이유는 무엇입니까?괄호가 필요한 이유에 대해.
이제 코드에 대해:
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입니다.끈. 개별 항목으로 직접 분할해야 합니다...
답변2
#1을 시도해 볼 수 있는 솔루션은 다음과 같습니다.
그만한 가치가 있기 때문에 null
이것은 empty
내 초기 생각과 다르지 않은 까다롭습니다.
가장 어려운 것은 다음 jq
을 사용하여 JSON 배열을 bash 배열로 변환하는 것입니다.
readarray -t ZEIT_DEPLOYMENT_ALIASES < <(jq --raw-output '.alias[]' < now.$CUSTOMER_REF_TO_DEPLOY.staging.json)
매우 감사합니다https://unix.stackexchange.com/a/615717/60329
ZEIT_DEPLOYMENT_ALIASES_JSON=$(cat now.$CUSTOMER_REF_TO_DEPLOY.staging.json | jq --raw-output '.alias')
echo "Custom aliases: " $ZEIT_DEPLOYMENT_ALIASES_JSON
# Convert the JSON array into a bash array - See https://unix.stackexchange.com/a/615717/60329
readarray -t ZEIT_DEPLOYMENT_ALIASES < <(jq --raw-output '.alias[]' < now.$CUSTOMER_REF_TO_DEPLOY.staging.json)
# Check if there are no aliases configured (it will return "null" in such case, which is not the same as bash "empty")
if [ "$ZEIT_DEPLOYMENT_ALIASES" != null ]
then
ZEIT_DEPLOYMENT_ALIASES_COUNT=${#ZEIT_DEPLOYMENT_ALIASES[@]}
echo "$ZEIT_DEPLOYMENT_ALIASES_COUNT alias(es) found. Aliasing them now..."
# For each alias configured, then assign it to the deployed domain
for DEPLOYMENT_ALIAS in "${ZEIT_DEPLOYMENT_ALIASES[@]}"; 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
감사합니다!