programing

Unix 쉘 스크립트에서 환경 변수가 설정되어 있는지 확인하는 간결한 방법은 무엇입니까?

bestprogram 2023. 4. 22. 10:57

Unix 쉘 스크립트에서 환경 변수가 설정되어 있는지 확인하는 간결한 방법은 무엇입니까?

작업을 시작하기 전에 특정 환경 변수가 설정되어 있는지 확인해야 하는 Unix 쉘 스크립트가 몇 개 있기 때문에 다음과 같은 작업을 수행합니다.

if [ -z "$STATE" ]; then
    echo "Need to set STATE"
    exit 1
fi  

if [ -z "$DEST" ]; then
    echo "Need to set DEST"
    exit 1
fi

타이핑이 많죠환경변수 세트가 설정되어 있는지 확인하기 위한 보다 우아한 관용어가 있습니까?

편집: 이러한 변수에는 의미 있는 기본값이 없습니다.설정되지 않은 변수가 있으면 스크립트는 에러 아웃됩니다.

파라미터 확장

분명한 답은 파라미터 확장의 특수한 형식 중 하나를 사용하는 것입니다.

: ${STATE?"Need to set STATE"}
: ${DEST:?"Need to set DEST non-empty"}

또는 아래 '큰따옴표 위치' 섹션을 참조하십시오.

: "${STATE?Need to set STATE}"
: "${DEST:?Need to set DEST non-empty}"

번째 바리안트('만 )?를 사용하려면 STATE를 설정해야 합니다.단, STATE=" (빈 문자열)은 문제가 없습니다.원하는 표기법은 아니지만 대체 표기법과 이전 표기법이 있습니다.

바리안트(「」를 사용):?) 를 . DEST가 있습니다.

메시지를 지정하지 않으면 셸은 기본 메시지를 제공합니다.

${var?}construct 7 UNIX Bourne Shell(1978년)입니다.${var:?}construct는 조금 더 최신입니다. III 그 .1981년 이전 시스템 III UNIX에 있었던 것, PWB UNIX에 있었다.【콘】【포식스】【바쉬】【바쉬】【바쉬】【바쉬】【바쉬】【바쉬】.

일반적으로 셸의 man 페이지에 Parameter Expansion이라고 하는 섹션으로 문서화되어 있습니다.예를 들어,bash이치노

${parameter:?word}

Null 또는 Unset이면 에러가 나타난다.파라미터가 늘 또는 설정되지 않은 경우 워드(또는 워드가 존재하지 않는 경우 그 취지의 메시지)의 전개는 표준 에러에 기입되어 인터랙티브하지 않은 경우 셸은 종료합니다.그렇지 않으면 매개 변수 값이 대체됩니다.

Colon 명령어

는 단순히 을 덧붙여야 합니다.colon 명령어는 를 평가한 후 성공합니다. 셸 입니다('알겠습니다' 앞#'이렇게 하다'오랫동안 본 셸 스크립트는 첫 번째 캐릭터로 콜론을 가지고 있었다. 첫 C C Shell')용인지 여부를 판단합니다.#('해시 Bourne (a): 알맹이가 '알맹이'대한 .#!/path/to/program 본 '''를 받았습니다# 규약은 요.' 라고 했어요하지만 만약 여러분이 콜론으로 시작하는 스크립트를 발견한다면, 이제 여러분은 이유를 알게 될 것입니다.


큰따옴표 위치

blong댓글로 물었다.

이 논의에 대해 어떻게 생각하세요?https://github.com/koalaman/shellcheck/issues/380#issuecomment-145872749

논의의 요지는 다음과 같습니다.

지,,,, 가가 …shellcheck 0에서는) 다음과 같은

In script.sh line 13:
: ${FOO:?"The environment variable 'FOO' must be set and non-empty"}
  ^-- SC2086: Double quote to prevent globbing and word splitting.

이 경우 어떻게 해야 하는지 조언해 주시겠어요?

는 ' 하다', '대로 하다' 입니다shellcheck★★★★★★★★★★★」

: "${STATE?Need to set STATE}"
: "${DEST:?Need to set DEST non-empty}"

그 이유를 설명하기 위해 다음을 공부하십시오.에 주의::명령어는 인수를 에코하지 않습니다(단, 셸은 인수를 평가합니다).를 사용합니다.printf "%s\n":.

$ mkdir junk
$ cd junk
$ > abc
$ > def
$ > ghi
$ 
$ x="*"
$ printf "%s\n" ${x:?You must set x}    # Careless; not recommended
abc
def
ghi
$ unset x
$ printf "%s\n" ${x:?You must set x}    # Careless; not recommended
bash: x: You must set x
$ printf "%s\n" "${x:?You must set x}"  # Careful: should be used
bash: x: You must set x
$ x="*"
$ printf "%s\n" "${x:?You must set x}"  # Careful: should be used
*
$ printf "%s\n" ${x:?"You must set x"}  # Not quite careful enough
abc
def
ghi
$ x=
$ printf "%s\n" ${x:?"You must set x"}  # Not quite careful enough
bash: x: You must set x
$ unset x
$ printf "%s\n" ${x:?"You must set x"}  # Not quite careful enough
bash: x: You must set x
$ 

「 」의 이 어떻게 에 주의해 .$x 번째 1번으로 됩니다.*전체 표현이 큰따옴표로 묶이지 않은 경우 파일 이름 목록을 표시합니다. 바로 런 this this입니다.shellcheck츠키다이중 따옴표로 둘러싸인 형태에 반대하지 않는다는 것을 확인하지는 못했지만, 괜찮다는 것은 합리적인 가정입니다.

이것을 시험해 보세요.

[ -z "$STATE" ] && echo "Need to set STATE" && exit 1;

질문은 사용 중인 셸에 따라 달라집니다.

본 포탄은 당신이 쫓는 것을 방해하는 것이 거의 없다.

그렇지만.....

어디서든 효과가 있어요.

CSH에서 멀리 떨어지려고 노력해봐.Bourne 쉘과 비교해서 벨과 휘파람이 더해진 것은 좋았지만, 지금은 정말 삐걱거리고 있습니다.믿을 수 없는 경우는, STDERR 를 csh로 구분해 주세요!(-:

여기에는 두 가지 가능성이 있습니다.위의 예, 즉 다음을 사용합니다.

${MyVariable:=SomeDefault}

처음으로 $MyVariable을 참조할 필요가 있습니다.그러면 env. var MyVariable이 사용되며 현재 설정되어 있지 않은 경우 나중에 사용할 수 있도록 SomeDefault 값이 변수에 할당됩니다.

다음과 같은 가능성도 있습니다.

${MyVariable:-SomeDefault}

이것은 이 구성을 사용하는 변수를 SomeDefault로 대체합니다.SomeDefault 값은 변수에 할당되지 않으며 MyVariable 값은 이 문이 발견된 후에도 늘이 됩니다.

가장 은 ''를 추가하는 이다.-ushebang(스크립트 맨 위의 행)으로 전환합니다.bash:

#!/bin/sh -u

이로 인해 바인딩되지 않은 변수가 존재할 경우 스크립트가 종료됩니다.

${MyVariable:=SomeDefault}

ifMyVariablenull이 아닌 설정된 경우 변수 값이 재설정됩니다(= 아무 일도 일어나지 않음).
않으면, 른른른른 else른,MyVariable로 설정되어 있다.SomeDefault.

됩니다.${MyVariable}변수를 설정하는 것만으로, 다음의 조작을 실시합니다.

MyVariable=${MyVariable:=SomeDefault}

제 생각에 #!/bin/sh에 대한 가장 간단하고 호환성이 높은 체크는 다음과 같습니다.

if [ "$MYVAR" = "" ]
then
   echo "Does not exist"
else
   echo "Exists"
fi

이것은 /bin/sh용이며 오래된 Solaris 시스템과도 호환됩니다.

bash4는 4.2의 「」를했습니다.-v빈 문자열까지 포함하여 이름이 임의의 값으로 설정되어 있는지 여부를 테스트하는 연산자.

$ unset a
$ b=
$ c=
$ [[ -v a ]] && echo "a is set"
$ [[ -v b ]] && echo "b is set"
b is set
$ [[ -v c ]] && echo "c is set"
c is set

항상 사용:

if [ "x$STATE" == "x" ]; then echo "Need to set State"; exit 1; fi

더 간결하진 않겠죠

CSH에 $가 있습니까?주.

저와 같은 미래의 사람들을 위해 변수 이름을 파라미터화하고 가변 크기의 변수 이름 목록을 루핑할 수 있도록 하고 싶었습니다.

#!/bin/bash
declare -a vars=(NAME GITLAB_URL GITLAB_TOKEN)

for var_name in "${vars[@]}"
do
  if [ -z "$(eval "echo \$$var_name")" ]; then
    echo "Missing environment variable $var_name"
    exit 1
  fi
done

여러 변수를 한 번에 체크할 수 있는 훌륭한 어설션을 작성할 수 있습니다.

#
# assert if variables are set (to a non-empty string)
# if any variable is not set, exit 1 (when -f option is set) or return 1 otherwise
#
# Usage: assert_var_not_null [-f] variable ...
#
function assert_var_not_null() {
  local fatal var num_null=0
  [[ "$1" = "-f" ]] && { shift; fatal=1; }
  for var in "$@"; do
    [[ -z "${!var}" ]] &&
      printf '%s\n' "Variable '$var' not set" >&2 &&
      ((num_null++))
  done

  if ((num_null > 0)); then
    [[ "$fatal" ]] && exit 1
    return 1
  fi
  return 0
}

호출 예:

one=1 two=2
assert_var_not_null one two
echo test 1: return_code=$?
assert_var_not_null one two three
echo test 2: return_code=$?
assert_var_not_null -f one two three
echo test 3: return_code=$? # this code shouldn't execute

출력:

test 1: return_code=0
Variable 'three' not set
test 2: return_code=1
Variable 'three' not set

이러한 주장은, https://github.com/codeforester/base/blob/master/lib/assertions.sh 를 참조해 주세요.

이것도 방법이 될 수 있습니다.

if (set -u; : $HOME) 2> /dev/null
...
...

http://unstableme.blogspot.com/2007/02/checks-whether-envvar-is-set-or-not.html

위의 솔루션 중 어느 것도 내 목적에 맞지 않았습니다.일부적으로는 긴 프로세스를 시작하기 전에 설정할 필요가 있는 변수의 무제한 목록을 환경에서 확인했기 때문입니다.결국 이렇게 됐어요.

mapfile -t arr < variables.txt

EXITCODE=0

for i in "${arr[@]}"
do
   ISSET=$(env | grep ^${i}= | wc -l)
   if [ "${ISSET}" = "0" ];
   then
      EXITCODE=-1
      echo "ENV variable $i is required."
   fi
done

exit ${EXITCODE}

외부 셸 스크립트를 사용하는 대신 로그인 셸의 함수에 로드하는 경향이 있습니다.set 변수가 아닌 환경변수를 체크하기 위한 도우미 기능으로 사용합니다.

is_this_an_env_variable ()
    local var="$1"
    if env |grep -q "^$var"; then
       return 0
    else
       return 1
    fi
 }

$?구문은 꽤 깔끔합니다.

if [ $?BLAH == 1 ]; then 
    echo "Exists"; 
else 
    echo "Does not exist"; 
fi

언급URL : https://stackoverflow.com/questions/307503/whats-a-concise-way-to-check-that-environment-variables-are-set-in-a-unix-shell