변수가 설정되어 있는지 확인하는 기능이있는 스크립트를 찾았지만 잘 이해하지 못했습니다.
check_if_variable_is_set() {
var_name=$1
if [ -z "${!var_name+x}" ]; then
false
else
true
fi
}
이 대체로 정확히 어떤 일이 발생합니까?
답변
에서 bash
쉘 ${!var}
변수 간접이다. 이름이로 유지되는 변수의 값으로 확장됩니다 $var
.
변수 확장 ${var+value}
은 값이 비어 있는지 여부에 관계없이 변수 가 설정 되면 확장되는 POSIX 확장 입니다 .value
var
이것들을 조합하면 이름이 유지되는 변수 가 설정 되면 ${!var+x}
확장됩니다 .x
$var
예:
$ foo=hello
$ var=foo
$ echo "${!var+$var is set, its value is ${!var}}"
foo is set, its value is hello
$ unset foo
$ echo "${!var+$var is set, its value is ${!var}}"
(출력으로 빈 줄)
문제의 기능이 단축 될 수 있습니다
check_if_variable_is_set () { [ -n "${!1+x}" ]; }
또는:
check_if_variable_is_set () { [ -v "$1" ]; }
또는:
check_if_variable_is_set()[[ -v $1 ]]
명명 된 변수가 설정되면 true가되고 그렇지 않으면 false가되는 변수 이름에 -v
대한 bash
테스트 는 어디에 있습니까 ?
POSIX는 다음과 같이 작성할 수 있습니다.
check_if_variable_is_set() { eval '[ -n "${'"$1"'+x}" ]'; }
해당 기능에 대한 인수가 공격자에 의해 제어 될 수있는 경우 모든 명령 주입 취약점이 될 수 있습니다. 로 예를 들어보십시오 check_if_variable_is_set 'a[$(id>&2)]'
.
이를 막기 위해 먼저 인수가 유효한 변수 이름인지 확인해야합니다. 변수의 경우 :
check_if_variable_is_set() {
case $1 in
("" | *[![:alnum:]_]* | [![:alpha:]_]*) false;;
(*) eval '[ -n "${'"$1"'+x}" ]'
esac
}
( 로케일에서[[:alpha:]]
알파벳 문자 를 확인 하는 반면, 일부 쉘은 변수에 휴대용 문자 세트의 알파벳 문자 만 허용합니다)