Bash에 변수가 설정되어 있는지 어떻게 알 수 있습니까?
예를 들어, 사용자가 함수에 첫 번째 매개 변수를 제공했는지 어떻게 확인합니까?
function a {
# if $1 is set ?
}
-v
테스트 를 통해 정확 하지만 새로운 버전에서만 사용할 수 있지만 bash
쉘을 통해 이식 할 수는 없습니다.
Bash에 변수가 설정되어 있는지 어떻게 알 수 있습니까?
예를 들어, 사용자가 함수에 첫 번째 매개 변수를 제공했는지 어떻게 확인합니까?
function a {
# if $1 is set ?
}
-v
테스트 를 통해 정확 하지만 새로운 버전에서만 사용할 수 있지만 bash
쉘을 통해 이식 할 수는 없습니다.
답변:
if [ -z ${var+x} ]; then echo "var is unset"; else echo "var is set to '$var'"; fi
어디 ${var+x}
A는 매개 변수 확장 하면 아무것도로 평가 var
해제하고, 문자열을 대체 x
그렇지.
이 구문 및 사용법은 따옴표가 필요없는 항목으로 확장되거나 (단어 구분이 없으므로 따옴표가 필요하지 않으므로) 따옴표를 생략 할 수 있으므로 ( ${var+x}
대신 대신 말할 수 "${var+x}"
있음 x
) 아무것도 (이 결과로 [ -z ]
편리하게 동일한 값 (true)으로 편리하게 평가됨 [ -z "" ]
)).
그러나 따옴표는 안전하게 생략 할 수 있으며 모든 사람에게 즉시 명백하지는 않지만 ( 이 주요 인용 부호의 첫 번째 작성자 에게는 주요 Bash 코더이기도 합니다.) 분명하지 않은 경우 가 있습니다. [ -z "${var+x}" ]
O (1) 속도 페널티의 가능한 작은 비용 으로 따옴표로 . 첫 번째 저자는이 솔루션에 코드를 주석 옆에 주석으로 추가 하여이 답변에 URL을 제공하며 여기에는 따옴표를 안전하게 생략 할 수있는 이유에 대한 설명도 포함됩니다.
if [ -z "$var" ]; then echo "var is blank"; else echo "var is set to '$var'"; fi
설정되지 않은 변수와 빈 문자열로 설정된 변수를 구분하지 않기 때문에 종종 잘못된 것입니다. 즉 var=''
, 그렇다면 위의 솔루션은 "var is blank"를 출력합니다.
사용자가 확장명 또는 추가 속성 목록을 지정해야하고 빈 문자열을 지정하지 않으면 기본값이 비어 있지 않은 값으로 설정되는 경우 설정되지 않은 "빈 문자열로 설정"의 구분이 필수적입니다. 스크립트가 빈 확장명 또는 추가 속성 목록을 사용하도록합니다.
모든 시나리오에서 구별이 필수적인 것은 아닙니다. 그런 경우에는 [ -z "$var" ]
괜찮을 것입니다.
${var+x}
되었습니다. 를 사용 [ -z ${var:+x} ]
하면와 다른 결과가 없습니다 [ -z "$var" ]
.
[ -z "" -a -z ${var+x} ]
가져 bash: [: argument expected
옵니다 (예 : zsh는 아님). 어떤 경우에는 작동하는 구문을 사용하여 답변을 싫어합니다.
[ -z $var ]
것은 따옴표를 생략하는 것보다 더 이상 "잘못"되지 않습니다. 어느 쪽이든, 당신은 당신의 입력에 대해 가정합니다. 빈 문자열을 설정되지 않은 것으로 처리하는 [ -z $var ]
것이 필요합니다.
null이 아닌 / 0이 아닌 문자열 변수를 확인하려면 (예 : 설정 한 경우)
if [ -n "$1" ]
의 반대입니다 -z
. -n
이상을 사용 하고 -z
있습니다.
당신은 그것을 다음과 같이 사용할 것입니다 :
if [ -n "$1" ]; then
echo "You supplied the first parameter!"
else
echo "First parameter not supplied."
fi
[]
쉘 (비 bash) 스크립트에서 더 잘 작동 한다는 데 동의합니다 .
set -u
.
다음은 매개 변수가 설정되지 않았는지 또는 비어 있는지 ( "Null") 또는 값으로 설정되어 있는지 테스트하는 방법입니다 .
+--------------------+----------------------+-----------------+-----------------+
| Expression | parameter | parameter | parameter |
| in script: | Set and Not Null | Set But Null | Unset |
+--------------------+----------------------+-----------------+-----------------+
| ${parameter:-word} | substitute parameter | substitute word | substitute word |
| ${parameter-word} | substitute parameter | substitute null | substitute word |
| ${parameter:=word} | substitute parameter | assign word | assign word |
| ${parameter=word} | substitute parameter | substitute null | assign word |
| ${parameter:?word} | substitute parameter | error, exit | error, exit |
| ${parameter?word} | substitute parameter | substitute null | error, exit |
| ${parameter:+word} | substitute word | substitute null | substitute null |
| ${parameter+word} | substitute word | substitute word | substitute null |
+--------------------+----------------------+-----------------+-----------------+
출처 : POSIX : 파라미터 확장 :
"대체"로 표시된 모든 경우에 표현은 표시된 값으로 대체됩니다. "assign"으로 표시된 모든 경우에 매개 변수에 해당 값이 지정되며 표현식도 대체됩니다.
이것을 실제로 보여주기 위해 :
+--------------------+----------------------+-----------------+-----------------+
| Expression | FOO="world" | FOO="" | unset FOO |
| in script: | (Set and Not Null) | (Set But Null) | (Unset) |
+--------------------+----------------------+-----------------+-----------------+
| ${FOO:-hello} | world | hello | hello |
| ${FOO-hello} | world | "" | hello |
| ${FOO:=hello} | world | FOO=hello | FOO=hello |
| ${FOO=hello} | world | "" | FOO=hello |
| ${FOO:?hello} | world | error, exit | error, exit |
| ${FOO?hello} | world | "" | error, exit |
| ${FOO:+hello} | hello | "" | "" |
| ${FOO+hello} | hello | hello | "" |
+--------------------+----------------------+-----------------+-----------------+
set foo; echo ${1:-set but null or unset}
echos "foo"; set --; echo ${1:-set but null or unset}
echos set but null ...
set
:-)
: ${FOOBAR:=/etc/foobar.conf}
은 변수가 설정되어 있지 않거나 null 인 경우 변수의 기본값을 설정하는 것입니다.
parameter
변수 이름입니다. word
는 사용중인 테이블의 구문과 변수 $parameter
가 설정, 설정되어 있지만 null인지 또는 설정되지 않은지에 따라 대체 할 문자열 입니다. 일을 더 복잡하게 만들지 않고 word
변수도 포함 할 수 있습니다! 이것은 문자로 구분 된 선택적 인수를 전달할 때 매우 유용 할 수 있습니다. 예를 들어 ${parameter:+,${parameter}}
, ,$parameter
설정되어 있지만 null이 아닌 경우 쉼표를 구분하여 출력합니다 . 이 경우, word
인,${parameter}
여기에 언급 된 대부분의 기술은 정확하지만 bash 4.2 는 변수 값을 테스트하는 대신 변수 존재에 대한 실제 테스트 ( man bash )를 지원합니다.
[[ -v foo ]]; echo $?
# 1
foo=bar
[[ -v foo ]]; echo $?
# 0
foo=""
[[ -v foo ]]; echo $?
# 0
특히이 방법은을 사용하는 것과 같은 다른 많은 방법과 달리 set -u
/ set -o nounset
모드 에서 설정되지 않은 변수를 확인하는 데 사용될 때 오류가 발생하지 않습니다 [ -z
.
[[ -v aaa ]]; echo $?
==>-bash: conditional binary operator expected
-bash: syntax error near 'aaa'
declare -a foo
다음 중 하나를 사용하여이를 수행하는 방법에는 여러 가지가 있습니다.
if [ -z "$1" ]
$ 1이 null이거나 설정되지 않은 경우 성공
[[ ]]
이식성 함정에 지나지 않습니다. if [ -n "$1" ]
여기에 사용되어야합니다.
foo=""
, $foo
값을 가지고 있지만, -z
단지 비어 있다고보고합니다. 그리고 -z $foo
당신이 있다면 날려 버릴 것 set -o nounset
입니다.
foo=
), 다음 러셀의 대답은 올바른 것입니다.
나는 항상 다른 답변 에서 POSIX 테이블을 느리게 느낀다는 것을 알았습니다. 그래서 여기에 내 테이크가 있습니다.
+----------------------+------------+-----------------------+-----------------------+
| if VARIABLE is: | set | empty | unset |
+----------------------+------------+-----------------------+-----------------------+
- | ${VARIABLE-default} | $VARIABLE | "" | "default" |
= | ${VARIABLE=default} | $VARIABLE | "" | $(VARIABLE="default") |
? | ${VARIABLE?default} | $VARIABLE | "" | exit 127 |
+ | ${VARIABLE+default} | "default" | "default" | "" |
+----------------------+------------+-----------------------+-----------------------+
:- | ${VARIABLE:-default} | $VARIABLE | "default" | "default" |
:= | ${VARIABLE:=default} | $VARIABLE | $(VARIABLE="default") | $(VARIABLE="default") |
:? | ${VARIABLE:?default} | $VARIABLE | exit 127 | exit 127 |
:+ | ${VARIABLE:+default} | "default" | "" | "" |
+----------------------+------------+-----------------------+-----------------------+
각 그룹 (앞에 콜론 이 있거나 없는)은 동일한 설정 및 설정되지 않은 경우를 가지므로 빈 경우를 처리 하는 방법 만 다릅니다 .
앞의 콜론에서 빈 케이스 와 설정되지 않은 케이스는 동일하므로 가능한 경우를 사용합니다 (즉 , 빈 케이스가 일치하지 않기 때문에 :=
, 아니라 사용 =
하십시오).
제목 :
VARIABLE
이 비어 있지 않음 ( VARIABLE="something"
)VARIABLE
은 비어 있음 / 없음 ( VARIABLE=""
)VARIABLE
이 없습니다 ( unset VARIABLE
)값 :
$VARIABLE
결과는 변수의 원래 값임을 의미합니다."default"
결과는 제공된 대체 문자열임을 의미합니다.""
결과가 null (빈 문자열)임을 의미합니다.exit 127
종료 코드 127로 스크립트 실행이 중지됨을 의미합니다.$(VARIABLE="default")
그 결과는 변수의 원래의 값을 의미 하고 향후 사용을 위해 변수에 할당 제공된 대체 문자열.VARIABLE=""
로 쓸 수 있습니다 VARIABLE=
. 여전히 전자는 더 읽기 쉽습니다.
변수가 비어 있지 않은지 확인하기 위해
if [[ $var ]]; then ... # `$var' expands to a nonempty string
반대로 변수가 설정되지 않았거나 비어 있는지 테스트합니다.
if [[ ! $var ]]; then ... # `$var' expands to the empty string (set or not)
변수가 설정되어 있는지 (빈 또는 비어 있지 않은지) 확인하기 위해
if [[ ${var+x} ]]; then ... # `var' exists (empty or nonempty)
if [[ ${1+x} ]]; then ... # Parameter 1 exists (empty or nonempty)
변수가 설정되지 않은 경우 반대 테스트 :
if [[ ! ${var+x} ]]; then ... # `var' is not set at all
if [[ ! ${1+x} ]]; then ... # We were called with no arguments
${variable+x}
를 얻는 데 사용됨)을 제공 했기 때문이라고 생각합니다 . 또한 왜 옳은지를 설명하는 훨씬 자세한 내용이 있습니다. x
$variable
${variable+x}
(명백한) 덜 읽을 수
Bash의 최신 버전 (4.2 이상에서 나는 생각하지만 확실하지는 않습니다)에서 다음을 시도합니다.
if [ ! -v SOMEVARIABLE ] #note the lack of a $ sigil
then
echo "Variable is unset"
elif [ -z "$SOMEVARIABLE" ]
then
echo "Variable is set to an empty string"
else
echo "Variable is set to some string"
fi
[ -v "$VARNAME" ]
정확하지는 않지만 단순히 다른 테스트를 수행합니다. 가정 VARNAME=foo
; 그런 다음 이름 foo
이 지정된 변수가 있는지 확인합니다 .
-v
은 POSIX를 준수하지 않습니다
[: -v: unexpected operator
, bash
대신에 사용해야 합니다 sh
.
if [ "$1" != "" ]; then
echo \$1 is set
else
echo \$1 is not set
fi
인수의 경우 일반적으로 인수의 수인 $ #를 테스트하는 것이 가장 좋습니다.
if [ $# -gt 0 ]; then
echo \$1 is set
else
echo \$1 is not set
fi
[ "$1" != "" ]
(또는 [ -n "$1" ]
) 생각합니다 ...
$1
빈 문자열로 설정 하면 실패 합니다.
$1
빈 문자열로 설정되어 있을 때 답변의 첫 번째 부분이 작동하지 않는 경우 유용한 해결 방법입니다 .
set -o nounset
켜져 있으면 실패합니다 .
bash
태그 때문에 Bash 중심의 답변을 많이 제공하고 있습니다.
Bash에서 명명 된 변수 만 처리하는 한이 함수는 변수가 빈 배열 인 경우에도 변수가 설정되었는지 항상 알려줍니다.
variable-is-set() {
declare -p "$1" &>/dev/null
}
Bash (최소한 3.0까지)에서 var
선언 / 설정 변수 인 경우 현재 유형 및 값에 관계없이 변수 를 설정 declare -p var
하는 declare
명령 을 출력하고 var
상태 코드 0
(성공)를 반환합니다 . var
선언되지 않은 경우 declare -p var
오류 메시지를 출력하고 stderr
상태 코드를 반환합니다 1
. 을 사용 하면 상태 코드를 변경하지 않고 &>/dev/null
일반 stdout
및 stderr
출력을 모두로 리디렉션합니다 /dev/null
. 따라서이 함수는 상태 코드 만 반환합니다.
[ -n "$var" ]
:${var[0]}
비어 있지 않은지 확인합니다 . (Bash$var
에서와 동일합니다${var[0]}
.)[ -n "${var+x}" ]
: 이${var[0]}
설정되어 있는지 확인합니다 .[ "${#var[@]}" != 0 ]
: 적어도 하나의 인덱스$var
가 설정되어 있는지 확인합니다 .
이것은 단지 (포함라는 이름의 변수를 작동 $_
)이 아닌 특수한 변수 ( $!
, $@
, $#
, $$
, $*
, $?
, $-
, $0
, $1
, $2
, ...,하고 나는 잊어 버린 수 있습니다). 이들 중 어느 것도 배열이 아니기 때문에 POSIX 스타일 [ -n "${var+x}" ]
은 이러한 모든 특수 변수에 대해 작동합니다. 그러나 많은 특수 변수는 함수가 호출 될 때 값 / 존재를 변경하므로 함수에 래핑하지 마십시오.
스크립트에 배열이 있고 가능한 많은 쉘과 호환되도록하려는 경우 typeset -p
대신 대신 사용을 고려하십시오 declare -p
. ksh는 전자를 지원하지만 이것을 테스트 할 수는 없다는 것을 읽었습니다. 나는 배쉬 3.0 이상 및 zsh을 5.5.1 각 지원이 모두 것을 알고 typeset -p
및 declare -p
만 다른 것이있는 사람이 다른에 대한 대안입니다. 그러나 나는 그 두 키워드 이상의 차이점을 테스트하지 않았으며 다른 쉘을 테스트하지 않았습니다.
POSIX sh 호환 스크립트가 필요하면 배열을 사용할 수 없습니다. 배열이 없으면 [ -n "{$var+x}" ]
작동합니다.
이 기능 설정 해제 변수 var
, eval
상기 S는 코드 전달 여부를 결정하는 테스트를 실행 var
에 의해 설정되는 eval
D 코드 최종적 다른 시험 결과의 상태 코드를 보여준다.
나는 건너 뛰는거야 test -v var
, [ -v var ]
그리고 [[ -v var ]]
그들이 POSIX 표준을 동일한 결과를 얻을 수 있기 때문에 [ -n "${var+x}" ]
, 배쉬 4.2 이상을 요구하면서. 테스트 한 쉘 (Bash 3.0 ~ 5.0 및 Zsh 5.5.1)과 typeset -p
동일하기 때문에 건너 뜁니다 declare -p
.
is-var-set-after() {
# Set var by passed expression.
unset var
eval "$1"
# Run the tests, in increasing order of accuracy.
[ -n "$var" ] # (index 0 of) var is nonempty
nonempty=$?
[ -n "${var+x}" ] # (index 0 of) var is set, maybe empty
plus=$?
[ "${#var[@]}" != 0 ] # var has at least one index set, maybe empty
count=$?
declare -p var &>/dev/null # var has been declared (any type)
declared=$?
# Show test results.
printf '%30s: %2s %2s %2s %2s\n' "$1" $nonempty $plus $count $declared
}
변수가 연관 배열로 선언되지 않은 경우 숫자가 아닌 배열 인덱스를 "0"으로 처리하는 Bash로 인해 테스트 결과가 예기치 않게 나타날 수 있습니다. 또한 연관 배열은 Bash 4.0 이상에서만 유효합니다.
# Header.
printf '%30s: %2s %2s %2s %2s\n' "test" '-n' '+x' '#@' '-p'
# First 5 tests: Equivalent to setting 'var=foo' because index 0 of an
# indexed array is also the nonindexed value, and non-numerical
# indices in an array not declared as associative are the same as
# index 0.
is-var-set-after "var=foo" # 0 0 0 0
is-var-set-after "var=(foo)" # 0 0 0 0
is-var-set-after "var=([0]=foo)" # 0 0 0 0
is-var-set-after "var=([x]=foo)" # 0 0 0 0
is-var-set-after "var=([y]=bar [x]=foo)" # 0 0 0 0
# '[ -n "$var" ]' fails when var is empty.
is-var-set-after "var=''" # 1 0 0 0
is-var-set-after "var=([0]='')" # 1 0 0 0
# Indices other than 0 are not detected by '[ -n "$var" ]' or by
# '[ -n "${var+x}" ]'.
is-var-set-after "var=([1]='')" # 1 1 0 0
is-var-set-after "var=([1]=foo)" # 1 1 0 0
is-var-set-after "declare -A var; var=([x]=foo)" # 1 1 0 0
# Empty arrays are only detected by 'declare -p'.
is-var-set-after "var=()" # 1 1 1 0
is-var-set-after "declare -a var" # 1 1 1 0
is-var-set-after "declare -A var" # 1 1 1 0
# If 'var' is unset, then it even fails the 'declare -p var' test.
is-var-set-after "unset var" # 1 1 1 1
헤더 행에 대응 시험 니모닉에 [ -n "$var" ]
, [ -n "${var+x}" ]
, [ "${#var[@]}" != 0 ]
, 및 declare -p var
는 각각.
test: -n +x #@ -p
var=foo: 0 0 0 0
var=(foo): 0 0 0 0
var=([0]=foo): 0 0 0 0
var=([x]=foo): 0 0 0 0
var=([y]=bar [x]=foo): 0 0 0 0
var='': 1 0 0 0
var=([0]=''): 1 0 0 0
var=([1]=''): 1 1 0 0
var=([1]=foo): 1 1 0 0
declare -A var; var=([x]=foo): 1 1 0 0
var=(): 1 1 1 0
declare -a var: 1 1 1 0
declare -A var: 1 1 1 0
unset var: 1 1 1 1
declare -p var &>/dev/null
3.0 이후 Bash에서 명명 된 변수를 테스트 할 때 (100 %?) 신뢰할 수 있습니다.[ -n "${var+x}" ]
POSIX 호환 상황에서는 안정적이지만 어레이를 처리 할 수 없습니다.- 변수가 비어 있지 않은지 확인하고 다른 쉘에서 선언 된 변수를 확인하기위한 다른 테스트가 있습니다. 그러나 이러한 테스트는 Bash 나 POSIX 스크립트에는 적합하지 않습니다.
declare -p var &>/dev/null
중이 하나만 작동합니다. 감사합니다!
... &> /dev/null
는 없으므로 단일 문자 편집을 할 수는 없습니다. 그러나 그것은 작동하지 않았습니다). 또한 지적한 것처럼 $1
이름이 지정된 변수 (예 :)에 대해 전환하도록 함수를 변경하는 것이 OUTPUT_DIR
좋습니다 $1
. 어쨌든, 그것은 중요한 편집입니다. 그렇지 않으면 코드는이라는 null
상대 디렉토리에있는 파일을 작성하려고합니다 dev
. BTW-좋은 답변입니다!
declare -p PATH &> /dev/null
returns 0 where as declare -p ASDFASDGFASKDF &> /dev/null
returns 1 (bash. 5.0.11 (1) -release)
declare var
var 변수를 선언하지만 다음 과 같이 설정 하지는 않습니다set -o nounset
.declare foo bar=; set -o nounset; echo $bar; echo $foo
/
! 나는 그것을 고쳤 지 만 논리는 특히 @xebeche의 의견에 비추어 함수를 보증하기에 충분히 혼란 스럽다고 생각합니다. @xebeche 저의 대답에는 불편합니다.… declare -p "$1" | grep =
또는 같은 것을 시도해야 할 것 같습니다 test -v "$1"
.
다음 을 사용하여 스크립트에서 설정되지 않았거나 비어 있는지 확인하려는 사용자의 경우 set -u
:
if [ -z "${var-}" ]; then
echo "Must provide var environment variable. Exiting...."
exit 1
fi
정규 [ -z "$var" ]
검사는 var; unbound variable
if로 실패 set -u
하지만 실패하지 않고 설정되지 않으면 빈 문자열로 [ -z "${var-}" ]
확장 됩니다 var
.
${var:-}
하지 ${var-}
. 그러나 Bash에서는 콜론 없이도 작동하는지 확인할 수 있습니다.
${var:-}
그리고 ${var-}
다른 것을 의미한다. ${var:-}
경우 문자열을 비우 확장됩니다 var
해제 또는 null 과 ${var-}
만 설정되지 않은 경우 빈 문자열로 확장됩니다.
이것은 나를 위해 일했습니다. 매개 변수가 설정되지 않은 경우 스크립트가 오류 메시지와 함께 종료되기를 원했습니다.
#!/usr/bin/env bash
set -o errexit
# Get the value and empty validation check all in one
VER="${1:?You must pass a version of the format 0.0.0 as the only argument}"
실행되면 오류와 함께 반환됩니다.
peek@peek:~$ ./setver.sh
./setver.sh: line 13: 1: You must pass a version of the format 0.0.0 as the only argument
값 set = VALID 또는 unset / empty = INVALID인지 확인하려면이 옵션을 사용하십시오.
TSET="good val"
TEMPTY=""
unset TUNSET
if [ "${TSET:-}" ]; then echo "VALID"; else echo "INVALID";fi
# VALID
if [ "${TEMPTY:-}" ]; then echo "VALID"; else echo "INVALID";fi
# INVALID
if [ "${TUNSET:-}" ]; then echo "VALID"; else echo "INVALID";fi
# INVALID
또는 짧은 테스트조차도 ;-)
[ "${TSET:-}" ] && echo "VALID" || echo "INVALID"
[ "${TEMPTY:-}" ] && echo "VALID" || echo "INVALID"
[ "${TUNSET:-}" ] && echo "VALID" || echo "INVALID"
그리고 이것은 질문에 대한 답변입니다. 값이 set / empty = VALID 또는 unset = INVALID인지 확인하려는 경우이를 사용하십시오.
"..- 1}"의 "1"은 중요하지 않으며 x와 같은 모든 것이 될 수 있습니다.
TSET="good val"
TEMPTY=""
unset TUNSET
if [ "${TSET+1}" ]; then echo "VALID"; else echo "INVALID";fi
# VALID
if [ "${TEMPTY+1}" ]; then echo "VALID"; else echo "INVALID";fi
# VALID
if [ "${TUNSET+1}" ]; then echo "VALID"; else echo "INVALID";fi
# INVALID
짧은 테스트
[ "${TSET+1}" ] && echo "VALID" || echo "INVALID"
[ "${TEMPTY+1}" ] && echo "VALID" || echo "INVALID"
[ "${TUNSET+1}" ] && echo "VALID" || echo "INVALID"
나는이 답변을 @ mklement0 (댓글)에 헌신하여 나에게 질문에 정확하게 대답하도록 도전했습니다.
참조 http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02
변수가 비어 있지 않은 값으로 설정되어 있는지 확인하려면 [ -n "$x" ]
다른 지시자가 이미 표시 한대로를 사용하십시오 .
대부분 빈 값을 가진 변수를 설정되지 않은 변수와 같은 방식으로 처리하는 것이 좋습니다. 그러나 필요한 경우 두 가지를 구별 할 수 있습니다. [ -n "${x+set}" ]
( if 가 설정 "${x+set}"
되어 set
있으면 x
빈 문자열로 확장됩니다.x
설정되지 않은 )
매개 변수가 전달되었는지 확인하려면 test $#
또는 함수에 전달 된 매개 변수의 수인 test 또는 함수에없는 스크립트에 전달하십시오 ( Paul 's answer 참조 ).
의 "매개 변수 확장"섹션을 읽으십시오 bash
매뉴얼 페이지 . 파라미터 확장은 설정되는 변수에 대한 일반적인 테스트를 제공하지 않지만, 설정되지 않은 경우 파라미터에 대해 수행 할 수있는 몇 가지 작업이 있습니다.
예를 들면 다음과 같습니다.
function a {
first_arg=${1-foo}
# rest of the function
}
할당되면 first_arg
같게 설정 $1
되고 그렇지 않으면 "foo"값을 사용합니다. 경우 a
절대적으로 하나의 매개 변수를 사용하고, 좋은 기본이 존재하지 않는해야한다 매개 변수가 지정되지 않은 경우, 오류 메시지와 함께 종료 할 수 있습니다 :
function a {
: ${1?a must take a single argument}
# rest of the function
}
( :
널 (NULL) 명령으로 사용 하면 인수 값이 확장됩니다. $1
이 예에서는 아무 것도 수행하고 싶지 않습니다. 설정되지 않은 경우 종료하면됩니다)
: ${var?message}
.
bash에서는 내장 -v
내부에서 사용할 수 있습니다 [[ ]]
.
#! /bin/bash -u
if [[ ! -v SOMEVAR ]]; then
SOMEVAR='hello'
fi
echo $SOMEVAR
[[ -z "$var" ]]
변수 사용 여부를 알 수있는 가장 쉬운 방법은 사용 이지만,이 옵션 -z
은 설정되지 않은 변수와 빈 문자열로 설정된 변수를 구별하지 않습니다.
$ set=''
$ [[ -z "$set" ]] && echo "Set" || echo "Unset"
Unset
$ [[ -z "$unset" ]] && echo "Set" || echo "Unset"
Unset
변수 유형 (env variable, parameter 또는 regular variable)에 따라 확인하는 것이 가장 좋습니다.
env 변수의 경우 :
[[ $(env | grep "varname=" | wc -l) -eq 1 ]] && echo "Set" || echo "Unset"
매개 변수의 경우 (예 $5
: 매개 변수 존재 여부 확인 ) :
[[ $# -ge 5 ]] && echo "Set" || echo "Unset"
일반 변수 (보조 기능을 사용하여 우아하게 수행) :
function declare_var {
declare -p "$1" &> /dev/null
}
declare_var "var_name" && echo "Set" || echo "Unset"
노트:
$#
: 위치 매개 변수의 수를 제공합니다.declare -p
: 매개 변수로 전달 된 변수의 정의를 제공합니다. 존재하는 경우 0을 리턴하고 그렇지 않은 경우 1을 리턴하고 오류 메시지를 인쇄합니다.&> /dev/null
:declare -p
리턴 코드에 영향을주지 않고 출력을 억제 합니다.
Bash 옵션 set -u
이 활성화되어 있으면 위의 답변이 작동하지 않습니다 . 또한 동적이지 않습니다. 예를 들어 "dummy"라는 이름으로 변수를 테스트하는 방법이 정의되어 있습니까? 이 시도:
is_var_defined()
{
if [ $# -ne 1 ]
then
echo "Expected exactly one argument: variable name as string, e.g., 'my_var'"
exit 1
fi
# Tricky. Since Bash option 'set -u' may be enabled, we cannot directly test if a variable
# is defined with this construct: [ ! -z "$var" ]. Instead, we must use default value
# substitution with this construct: [ ! -z "${var:-}" ]. Normally, a default value follows the
# operator ':-', but here we leave it blank for empty (null) string. Finally, we need to
# substitute the text from $1 as 'var'. This is not allowed directly in Bash with this
# construct: [ ! -z "${$1:-}" ]. We need to use indirection with eval operator.
# Example: $1="var"
# Expansion for eval operator: "[ ! -z \${$1:-} ]" -> "[ ! -z \${var:-} ]"
# Code execute: [ ! -z ${var:-} ]
eval "[ ! -z \${$1:-} ]"
return $? # Pedantic.
}
넌 할 수있어:
function a {
if [ ! -z "$1" ]; then
echo '$1 is set'
fi
}
-n
있고 부정 할 수 없습니다 -z
.
$1
에 따옴표가 필요합니다 [ ! -z "$1" ]
. 또는 [[ ! -z $1 ]]
bash / ksh / zsh로 작성할 수 있습니다 .
$1
빈 문자열로 설정 하면 실패 합니다.
내가 선호하는 방법은 다음과 같습니다.
$ var=10
$ if ! ${var+false};then echo "is set";else echo "NOT set";fi
is set
$ unset -v var
$ if ! ${var+false};then echo "is set";else echo "NOT set";fi
NOT set
따라서 기본적으로 변수가 설정되면 변수는 "결과의 부정 false
"이됩니다 (무엇을 true
= "설정 됨").
그리고 설정이 해제되면 true
빈 결과가로 평가 되는대로 " 결과의 부정 " true
이됩니다 (따라서 false
"설정되지 않음"으로 종료됩니다 ).
if [[ ${1:+isset} ]]
then echo "It was set and not null." >&2
else echo "It was not set or it was null." >&2
fi
if [[ ${1+isset} ]]
then echo "It was set but might be null." >&2
else echo "It was was not set." >&2
fi
에서 무언가를 확인하려면이 작업을 수행하는 훨씬 더 나은 코드를 찾았습니다 $@
.
[[$ 1 = ""]] 인 경우 그때 에코 '$ 1이 비어 있습니다' 그밖에 에코 '$ 1이 채워졌습니다' fi
왜이 모든거야? 모든에 $@
배쉬에 존재하지만, 기본적으로의 빈, 그래서 test -z
하고 test -n
당신을 도울 수 있습니다.
업데이트 : 매개 변수에서 문자 수를 계산할 수도 있습니다.
[$ {# 1} = 0] 인 경우 그때 에코 '$ 1이 비어 있습니다' 그밖에 에코 '$ 1이 채워졌습니다' fi
이것이 내가 매일 사용하는 것입니다.
#
# Check if a variable is set
# param1 name of the variable
#
function is_set()
{
[[ -n "${1}" ]] && test -n "$(eval "echo "\${${1}+x}"")"
}
이것은 Linux 및 Solaris에서 bash 3.0까지 잘 작동합니다.
bash-3.00$ myvar="TEST"
bash-3.00$ is_set myvar ; echo $?
0
bash-3.00$ mavar=""
bash-3.00$ is_set myvar ; echo $?
0
bash-3.00$ unset myvar
bash-3.00$ is_set myvar ; echo $?
1
나는 bash의 조잡한 세부 사항을 숨기는 보조 기능을 좋아합니다. 이 경우 그렇게하면 더 많은 (숨겨진) 조잡함이 추가됩니다.
# The first ! negates the result (can't use -n to achieve this)
# the second ! expands the content of varname (can't do ${$varname})
function IsDeclared_Tricky
{
local varname="$1"
! [ -z ${!varname+x} ]
}
Jens와 Lionel의 답변에서 영감을 얻은이 구현에 처음으로 버그가 있었으므로 다른 솔루션을 생각해 냈습니다.
# Ask for the properties of the variable - fails if not declared
function IsDeclared()
{
declare -p $1 &>/dev/null
}
더 직관적이고 이해하기 쉽고 이해하기 쉽고 기억하기 쉽습니다. 테스트 사례에 따르면 다음과 같습니다.
function main()
{
declare -i xyz
local foo
local bar=
local baz=''
IsDeclared_Tricky xyz; echo "IsDeclared_Tricky xyz: $?"
IsDeclared_Tricky foo; echo "IsDeclared_Tricky foo: $?"
IsDeclared_Tricky bar; echo "IsDeclared_Tricky bar: $?"
IsDeclared_Tricky baz; echo "IsDeclared_Tricky baz: $?"
IsDeclared xyz; echo "IsDeclared xyz: $?"
IsDeclared foo; echo "IsDeclared foo: $?"
IsDeclared bar; echo "IsDeclared bar: $?"
IsDeclared baz; echo "IsDeclared baz: $?"
}
main
테스트 사례는 또한 var를 선언 local var
하지 않는 것을 보여줍니다 ( '='가 뒤 따르지 않는 한). 꽤 오랫동안 나는 이런 식으로 변수를 선언했다고 생각했는데, 단지 내가 단지 나의 의도를 표현했다는 것을 발견하기 위해서였다.
IsDeclared_Tricky xyz : 1
IsDeclared_Tricky foo : 1
IsDeclared_Tricky 바 : 0
IsDeclared_Tricky baz : 0
IsDeclared xyz : 1
IsDeclared foo : 1
IsDeclared 바 : 0
IsDeclared baz : 0
보너스 : 유스 케이스
나는 주로이 테스트를 사용하여 다소 "우아한"안전한 방법 (거의 인터페이스와 유사한 )으로 함수에 매개 변수를 제공 (및 리턴 )합니다.
#auxiliary functions
function die()
{
echo "Error: $1"; exit 1
}
function assertVariableDeclared()
{
IsDeclared "$1" || die "variable not declared: $1"
}
function expectVariables()
{
while (( $# > 0 )); do
assertVariableDeclared $1; shift
done
}
# actual example
function exampleFunction()
{
expectVariables inputStr outputStr
outputStr="$inputStr world!"
}
function bonus()
{
local inputStr='Hello'
local outputStr= # remove this to trigger error
exampleFunction
echo $outputStr
}
bonus
모든 변수와 함께 호출 된 경우 변수를 선언해야합니다.
안녕하세요 세상!
그밖에:
오류 : 변수가 선언되지 않았습니다 : outputStr
모든 답변을 감추고 나면 다음과 같이 작동합니다.
if [[ -z $SOME_VAR ]]; then read -p "Enter a value for SOME_VAR: " SOME_VAR; fi
echo "SOME_VAR=$SOME_VAR"
SOME_VAR
내가 가진 것 대신에 넣지 않으면 $SOME_VAR
빈 값으로 설정됩니다. $
이것이 작동하려면 필요합니다.
set -u
인쇄되는 효과 unboud variable
오류
var가 설정되어 있는지 확인하려면
var=""; [[ $var ]] && echo "set" || echo "not set"
$var
빈 문자열로 설정 하면 실패 합니다.
변수가 바운드 또는 언 바운드인지 테스트하려면 nounset 옵션을 설정 한 후에도 잘 작동합니다.
set -o noun set
if printenv variableName >/dev/null; then
# variable is bound to a value
else
# variable is unbound
fi
set -o nounset
아니라고 생각합니다 set -o noun set
. 이것은 export
ed 된 변수에 대해서만 작동합니다 . 또한 실행 취소하기 어려운 방식으로 설정을 변경합니다.
나는 항상 처음으로 코드를 보는 사람이 이해하기 쉽다는 사실에 근거하여 항상 이것을 사용합니다.
if [ "$variable" = "" ]
then
echo "Variable X is empty"
fi
그리고 비어 있지 않은지 확인하려면;
if [ ! "$variable" = "" ]
then
echo "Variable X is not empty"
fi
그게 다야.
[[ ... ]]
대신 을 사용해야 합니다 [ ... ]
. 후자는 실제로 외부 명령이며 변수 설정 여부에 대한 가시성이 없습니다.
if test $# -gt 0; then printf 'arg <%s>\n' "$@"; fi
.