변수가 설정되었는지 확인하는 기능이 있는 스크립트를 찾았지만 잘 이해가 되지 않습니다.
check_if_variable_is_set() {
var_name=$1
if [ -z "${!var_name+x}" ]; then
false
else
true
fi
}
이번 교체로 정확히 무슨 일이 일어날까요?
답변1
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 ]]
변수 이름에 대한 테스트는 어디에 -v
있습니까 ? 명명된 변수가 설정되어 있으면 true이고, 그렇지 않으면 false입니다.bash
POSIXly에서는 다음과 같이 작성할 수 있습니다.
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:]]
알파벳 문자는 확인됩니다.당신의 지역에서일부 쉘은 변수의 이식 가능한 문자 세트에서 알파벳 문자만 허용합니다.