이진 연산자 예상-쉘 스크립트 인수에 대한 인용 질문

쉘 스크립트를 실행할 때 인수를 추가하는 방법에 대한 질문이 있습니다.

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 */ 

이게 인용 문제인 경우 인수를 어떻게 구성합니까 (백 슬래시를 사용하여 공백을 이스케이프하지 않음)? 물론 변경이 필요할 수 있습니다. 스크립트에 대해서도 허용되는 솔루션입니다.

댓글

  • $3는 세 개의 매개 변수가 있는지 확인하는 것입니다. 매개 변수 수를 포함하는 더 간단한 $# 셸 변수를 사용할 수 있습니다. if [ $# -ne 3 ].

답변

예, 그게 인용구입니다. 문제 : [ ! $3 ][ ! south brisbane qld ]로 확장 됨 ([와 ). 그리고 네 개의 인수를 볼 때 첫 번째 인수는 !, [[ ! arg1 op arg2 ]와 같이 op는 이항 연산자입니다. (이 역시 [ .. ][[ .. ]]; 이 Q 참조 또한이 Q )

brisbane는 유효한 연산자가 아니므로 불평하고 2를 반환합니다. 이는 거짓이므로 if가 실행되지 않습니다. 오류와 일반 실패 테스트의 차이를 알려면 2에 대해 반환 값을 명시 적으로 테스트해야합니다.

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


[ ! "$3" ] 또는 를 사용하여 문자열을 [에 대한 하나의 인수로 유지합니다.

물론 테스트의 의미를 반전시킬 수도 있습니다. if 내부의 실제 작업이므로 테스트 오류로 인해 기본 명령이 실행되지 않습니다.하지만 코드 구조가 좀 더 명확하지 않게됩니다.

댓글

  • 좋습니다. 따라서 작동하는 이유는 오류가 발생하더라도 $ 3이 비어 있지 않기 때문입니다. ' ! 테스트를 통과 한 다음 iptables 명령에 인용되어 있으므로 공백을 포함하는 확장이 이미 처리되었습니다. 맞습니까?
  • 그리고 그들은 ' iptables 행의 매개 변수도 인용하고 싶습니다.
  • @WEBjuju, 아 예, 그에 대해 쓰려고했고 작동하는 이유를 편집했습니다. 그리고 예,iptables 명령에 따옴표가있어서 잘 작동합니다.
  • @ilkkachu gotcha, 네, 내 쪽에서는 어리석은 것 같습니다. 어떻게 든 무의식적으로 알고 있었지만 ' 작업 솔루션에 대한 지식을 가져올 수 없었습니다. 나는 지금까지이 기본 세입자를 모르고 왠지 혼란스러워했지만 진지하게 레벨 업했습니다. 감사합니다!

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다