Bash 비교: 변수에 공백과 셸 구문이 포함된 경우 구문 오류/코드 삽입을 방지합니다.

Bash 비교: 변수에 공백과 셸 구문이 포함된 경우 구문 오류/코드 삽입을 방지합니다.

변수값을 무엇인가와 비교할 때(산술비교를 하려고 하므로 사용할 수 없습니다.)"x$VAR" == "xyes"장난), 변수에 공백 및/또는 쉘 구문이 포함되어 있을 때 이를 방지하는 방법은 무엇입니까?

$ (b="-z foo"; if [[ "$b" -eq 5 ]]; then echo foo; fi)
+(:50): b='-z foo'
+(:50): [[ -z foo -eq 5 ]]
-bash: [[: -z foo: syntax error in expression (error token is "foo")

시도됨: 단일 및 이중 괄호, 산술 평가( (())), 인용 및 인용되지 않음, "${b##-}"심지어 "${b@Q}"확인됨 ;https://mywiki.wooledge.org/BashPitfalls.

답변1

값이 10진수여야 하고 사용자에게 혼란스러운 오류 및 스크립트 중단 이벤트가 발생하지 않도록 하려면 변수에 숫자가 아닌 문자가 있는지 테스트하고 자체 오류 메시지로 처리합니다.

[[ -z ${val} ]] && {
  echo "$0: Oops, \"${val}\" is empty" >&2
  exit 1
}
[[ ${val} =~ [^[:digit:]] ]] && {
  echo "$0: Oops, non-numeric characters found in \"${val}\"" >&2
  exit 1
}

값이 공백이 필요하지 않은 문자열인 경우 유사한 기술을 사용하여 공백을 확인합니다.

[[ ${val} =~ [[:blank:]] ]] && {
  echo "$0: Oops, \"${val}\" contains space or tab characters" >&2
  exit 1
}

줄 바꿈, 캐리지 리턴, 폼 피드 및 세로 탭도 테스트하려면 [:space:]문자 클래스를 사용하세요.

이것이 제가 bash v4.x 스크립트에서 하고 있는 일입니다. 다른 쉘에 대한 제안은 없습니다.

답변2

[[ ... ]]ksh 구성(bash를 포함하지만 변형이 있는 일부 쉘에 의해 복사됨) 에서 산술 연산자의 피연산자는 산술 표현식으로 해석됩니다.정리 없이 외부에서 제공되는 입력을 사용하면 임의 실행 취약점이 발생합니다..

(( a == b ))(ksh에서도) 동일하게 적용됩니다 .

[[ ... ]]이를 방지하려면 원하는 입력과 일치하지 않는 항목을 수동으로 삭제하고 거부하거나 허용하려는 형식만 허용하는 상수 이외의 명령을 사용하여 허용할 입력을 결정해야 합니다 .

bash 및 기타 쉘에서 선택적 선행 기호와 주변 공백이 있는 십진 정수 상수를 허용하려는 경우 [십진 정수만 허용하는 내장 함수라고도 불리는 기능을 사용할 수 있습니다.test

[ "$b" -eq 5 ]

$b10진 정수 상수가 아닌 경우 [오류로 인해 실패하고 상태 2를 반환합니다.

모든 POSIX 지정 산술 표현식 상수(예: 12, -1, 010, 0x5)를 허용하려면 상수 또는 빈 문자열(선택적으로 둘러싸인 공백으로 구분)이 포함된 경우 산술 표현식 내에서 기본 변수만 허용하는 접근 방식을 채택할 dash수 있습니다.

VAL="$b" dash -c '[ "$((VAL))" -eq 5 ]'

$b(유효한 상수가 포함되지 않은 경우 상태는 다시 2가 됩니다.)

1.123(일부 로케일 및 일부 awk 구현에서는 1,123일 수 있음), 50e-1 또는 그 이상과 같은 더 많은 숫자를 허용하려면 다음을 사용할 수 있습니다 awk.

awk -- 'BEGIN{exit !(ARGV[1] == 5)}' "$b"

여기서 $b숫자로 인식되지 않으면 문자열 비교를 수행하여 false를 반환합니다. GNU를 사용하면 awk반환 여부를 확인하여 문자열이 숫자로 인식되는지 알 수 있습니다.typeof(ARGV[1])strnum

또한 범위와 정밀도에도 주의를 기울이세요. 4.9999999999999999 또는 18446744073709551621 (2 64 +5)는 요청하는 사람에 따라 5와 동일하게 간주될 수 있습니다.

관련 정보