다른 경우에는 APP_ENV
"prod"가 비어 있어야 합니다.DATABASE_DISABLE_MIGRATIONS
true
~하지 않는 한 DATABASE_DISABLE_MIGRATIONS
비어 있거나 null입니다. 즉, 그것은가치는 존중되어야합니다자동 할당은 다음과 같은 경우에만 발생해야 합니다.설정되지 않음.
원래DATABASE_DISABLE_MIGRATIONS |
APP_ENV |
새로운DATABASE_DISABLE_MIGRATIONS |
---|---|---|
비어 있거나 비어 있음 | 어느 | 원래의 가치를 유지하다 |
길이가 0이 아닌 문자열 | 어느 | 원래의 가치를 유지하다 |
설정되지 않음 | "제품" | 비어 있는 |
설정되지 않음 | 비어 있거나 "prod"가 아님 | "진짜" |
저는 쉘(POSIX)을 배우기 시작했고 다음 코드를 사용하여 이 작업을 성공적으로 수행했습니다.
#!/bin/sh
if [ "${DATABASE_DISABLE_MIGRATIONS+set}" != set ]; then
: ${DATABASE_DISABLE_MIGRATIONS:=$( [ "$APP_ENV" = "prod" ] || echo "true" )}
fi
# Just for debug (not meant to be in the single-line assignment of course)
if [ -z "$DATABASE_DISABLE_MIGRATIONS" ]; then
echo "Empty value, migrations ENABLED"
else
echo "Not empty value, migrations DISABLED"
fi
위 코드를 한 줄짜리 문장으로 작성할 수 있나요?
설정되지 않은 문자열, null 또는 빈 문자열을 고려할 때 한 줄짜리 명령문을 만드는 것은 쉽습니다. 저는 종종 다음을 사용하게 됩니다.
: ${FOO:=$( [ "$APP_ENV" = "prod" ] || echo "true" )}
변수는 설정되지 않은 경우, null이거나 비어 있고 "prod"가 아닌 경우 FOO
값을 가져옵니다 .true
FOO
APP_ENV
어쩌면 비슷한 "바로가기"가 누락된 것일까요?
답변1
2개의 변수를 사용하는 Case 문은 다음과 같습니다.
case "${DATABASE_DISABLE_MIGRATIONS}:${APP}" in
?*:* | "":prod) # not empty, or prod
echo "Not empty value, migrations DISABLED"
;;
*) echo "Empty value, migrations ENABLED"
;;
esac
하지만 이는 "비어 있음"과 "설정되지 않음"을 구분하지 않습니다. 변수 값 중 하나에 콜론이 포함되어 있는 경우에도 스푸핑될 가능성이 있습니다.
기반으로
원래DATABASE_DISABLE_MIGRATIONS |
APP_ENV |
새로운DATABASE_DISABLE_MIGRATIONS |
---|---|---|
비어 있거나 비어 있음 | 어느 | 원래의 가치를 유지하다 |
길이가 0이 아닌 문자열 | 어느 | 원래의 가치를 유지하다 |
설정되지 않음 | "제품" | 비어 있는 |
설정되지 않음 | 비어 있거나 "prod"가 아님 | "진짜" |
자신을 POSIX로 제한하지 마십시오. "설정되지 않음"은조정변수를 사용하려면 다음을 수행합니다.
if [[ ! -v DATABASE_DISABLE_MIGRATIONS ]]; then
if [[ $APP == prod ]]; then
DATABASE_DISABLE_MIGRATIONS=""
else
DATABASE_DISABLE_MIGRATIONS=true
fi
fi
이는 분명히 귀하의 한 줄 희망 사항을 충족시키지 못하지만 귀하의 의도를 전달하는 가장 읽기 쉬운 방법이라고 생각합니다.
답변2
주문하다:
[ -z "${DATABASE_DISABLE_MIGRATIONS+x}" ] && [ "$APP_ENV" != "prod" ] && DATABASE_DISABLE_MIGRATIONS=true
설명하다:
ㅏ논평이 정보를 사용하여 변수를 확인함을 나타냅니다.
[ -z "$DATABASE_DISABLE_MIGRATIONS" ]
이 정보는 질문의 일부여야 합니다.
"$DATABASE_DISABLE_MIGRATIONS"
(또는)을 사용하지 않는 한 set -u
, 설정되지 않은 변수나 빈 문자열에 대해 확장 결과가 동일하므로 set -o nounset
요구 사항이 단순화됩니다. 설정되지 않은 변수를 명시적인 null 값으로 바꾸지 마십시오. "prod"
설정하지 않은 채로 두면 동일한 테스트 결과를 얻을 수 있기 때문입니다.
따라서 알고리즘은 다음과 같이 단순화될 수 있습니다.
- (DATABASE_DISABLE_MIGRATIONS가 설정되지 않고 APP_ENV가 "prod"가 아닌 경우) DATABASE_DISABLE_MIGRATIONS를 "true"로 설정합니다.
- (그렇지 않으면 아무것도 하지 않음)
물론 이것을 여러 줄로 작성할 수 있으므로 코드가 더 명확해 지지만 한 줄이 아니며 질문에 대한 솔루션보다 훨씬 짧지 않습니다.
if [ -z "${DATABASE_DISABLE_MIGRATIONS+x}" ] && [ "$APP_ENV" != "prod" ]
then
DATABASE_DISABLE_MIGRATIONS=true
fi
답변3
따라서 변수가 설정되지 않은 경우 기본값으로 설정하고 그렇지 않으면 원래 값을 유지하시겠습니까? (여기서 기본값은 다른 변수에 따라 다르지만 이로 인해 산만해지지 않도록 합시다.)
그렇다면 다음과 같이 하는 것이 더 나을 수도 있습니다.
# don't disable migrations in production by default
if [ "$APP_ENV" = prod ]; then
default_DATABASE_DISABLE_MIGRATIONS=
else
default_DATABASE_DISABLE_MIGRATIONS=true
fi
# set default value if unset
if [ "${DATABASE_DISABLE_MIGRATIONS+set}" != set ]; then
DATABASE_DISABLE_MIGRATIONS=$default_DATABASE_DISABLE_MIGRATIONS
fi
또는 더 짧은 것:
# don't disable migrations in production by default
default_DATABASE_DISABLE_MIGRATIONS=true
if [ "$APP_ENV" = prod ]; then
default_DATABASE_DISABLE_MIGRATIONS=
fi
# set default value if unset
: "${DATABASE_DISABLE_MIGRATIONS=$default_DATABASE_DISABLE_MIGRATIONS}"
관련 값을 기반으로 한 코드 골프는 다른 값에 대해서도 비슷한 로직을 사용해야 한다면 전체 코드를 수정해야 하기 때문에 비생산적인 것 같습니다. 다른 유사한 사례에 적용할 수 있는 간단한 솔루션을 개발하는 것이 좋습니다. 마지막 줄은 질문 제목에서 요청한 것과 거의 비슷하지만 변수가 설정되지 않은 경우 한 줄의 셸 할당만 수행합니다. ( "${var:=default}"
빈 값 집합에도 작동합니다.)
또한 최종 변수가 부정되지 않으면 독자에게 더 명확해질 수 있다는 점도 지적하고 싶습니다. [ -z "$DATABASE_DISABLE_MIGRATIONS" ]
기본적으로 "마이그레이션이 비활성화되지 않은 경우"와 같은 변수 사용 및 테스트를 언급했습니다 . 이는 "마이그레이션이 활성화된 경우"와 동일하며 변수를 사용하면 작성하기가 더 쉽습니다 $DATABASE_ENABLE_MIGRATIONS
.
답변4
가능한:
case ${DATABASE_DISABLE_MIGRATIONS++}:$APP_ENV in
(:prod) DATABASE_DISABLE_MIGRATIONS= ;;
(:* ) DATABASE_DISABLE_MIGRATIONS=true;;
esac
다른 코드와 마찬가지로 한 줄에 넣고 줄을 연결하거나 다음과 같이 압축할 수도 있습니다.
case ${DATABASE_DISABLE_MIGRATIONS++}:$APP_ENV in(:prod)DATABASE_DISABLE_MIGRATIONS=;;(:*)DATABASE_DISABLE_MIGRATIONS=true;esac
) 그러나 나는 이점을 보지 못했습니다.
실행은 $(... echo ...)
추가 프로세스를 분기하고(ksh93 제외) echo
명령을 실행하고 파이프를 통해 해당 명령을 보내고 받는 것을 의미합니다. 이는 수십만 개 이상의 CPU 명령을 의미하는 반면, 이러한 간단한 셸 할당 및 패턴 일치는 단지 수백 개가 있습니다. , 그래서 나에게는 조금 어리석은 느낌이 듭니다.