바이너리 연산자 필요 - 쉘 스크립트 매개변수에 대한 인용 문제

바이너리 연산자 필요 - 쉘 스크립트 매개변수에 대한 인용 문제

쉘 스크립트 실행 시 매개변수를 추가하는 방법에 대해 질문이 있습니다.

IP 범위를 차단하는 데 도움이 되는 간단한 스크립트가 있습니다.

~/block_ip.sh:

if [ ! $3 ]
then
 echo "usage ~/block_ip.sh (DROP/ACCEPT) '0.0.0.0' 'amsterdam'"
 exit 1
fi

echo "adding $3"
sudo iptables -I INPUT -s $2 -j $1 -m comment --comment "$3"

매개변수 없이 이 작업을 수행하면 예상한 대로 출력됩니다.

~$ ./block_ip.sh
usage ~/block_ip.sh (DROP/ACCEPT) '0.0.0.0' 'amsterdam'

그런데 공백이 예상치 못한 출력의 원인인 것 같습니다."예상되는 이진 연산자":

~$ ./block_ip.sh DROP '1.0.0.0/8' 'south brisbane qld'
./block_ip.sh: line 1: [: brisbane: binary operator expected
adding south brisbane au

그러나 예상치 못한 결과가 나왔음에도 불구하고 이를 추가합니다.

Chain INPUT (policy ACCEPT)
num  target     prot opt source           destination
1    DROP       all  --  1.0.0.0/8        anywhere         /* south brisbane au */

이것이 인용 문제인 경우 공백을 이스케이프하기 위해 백슬래시를 사용하지 않고 매개 변수를 어떻게 구성합니까? 물론 스크립트를 변경해야 할 수도 있다고 예상하며 이는 수용 가능한 솔루션입니다.

답변1

예, 인용 문제입니다. [ ! $3 ](및 [ ! south brisbane qld ]그 사이의 네 가지 인수)로 확장됩니다. 4개의 매개변수(그 중 첫 번째 매개변수는 a )가 표시되면 where is 이진 연산자와 같은 내용이 표시될 것으로 예상됩니다. (이것은 다시 와 사이의 차이점 중 하나입니다.[]![[ ! arg1 op arg2 ]op[ .. ][[ .. ]]이 질문을 봤어요그리고그리고 이 Q)

brisbane유효한 연산자가 아니므로 불평하고 잘못된 2를 반환하므로 의 if명령문이 실행되지 않습니다. 일반적인 실패 테스트와 오류를 구별하려면 2에 따라 반환 값을 명시적으로 테스트해야 합니다.

반면에 $3비어 있으면 테스트는 [ ! ]단일 인수 테스트가 되어 유일한 인수가 비어 있지 않은지 확인합니다(즉, 단일 문자 문자열임 !). 이 경우 예상대로 작동하지만 예상한 이유가 아닐 수도 있습니다.


문자열을 인수 중 하나로 유지 [ ! "$3" ]하거나 유지 하려고 합니다 .[ -z "$3" ][

물론 테스트의 의미를 반대로 바꾸고 에서 실제 작업을 수행하여 if테스트 오류가 기본 명령 실행을 방지하도록 할 수도 있습니다. 그러나 이는 코드 구조를 더욱 불분명하게 만듭니다.

관련 정보