`(`, `)` 및 `test`에 대한 POSIX 설명을 이해하는 방법은 무엇입니까?

`(`, `)` 및 `test`에 대한 POSIX 설명을 이해하는 방법은 무엇입니까?

~에서POSIX 2013:

-a 및 -o 기본 바이너리와 "(" 및 ")" 연산자를 지정하는 XSI 확장은 더 이상 사용되지 않는 것으로 표시되었습니다. (이를 사용하는 많은 표현식은 평가되는 특정 표현식에 따라 구문에 의해 모호하게 정의됩니다.) 이러한 표현식을 사용하는 스크립트는 아래 주어진 형식으로 변환되어야 합니다. 많은 구현이 이러한 쓸모없는 형식을 계속 지원하지만, 스크립트는 사용자 제공 입력을 처리할 때 매우 주의해야 합니다. 이 입력이 이러한 기본 및 연산자와 혼동될 수 있기 때문입니다. 애플리케이션 개발자가 스크립트에 대한 입력을 생성하는 모든 상황을 알지 않는 한 다음과 같이 호출합니다.

test "$1" -a "$2"

다음과 같이 작성되어야 합니다:

test "$1" && test "$2"

  1. "'(' 및 ')' 연산자는 더 이상 사용되지 않는 것으로 표시되었습니다."

    ()명령을 그룹화하고 하위 쉘을 생성하는 연산자는 무엇 입니까?

    더 이상 사용되지 않는 경우 대체품은 무엇입니까?

  2. test "$1" -a "$2"로 교체해야 할까요 test "$1" && test "$2", 아니면 로 교체해야 할까요 (( test "$1" && test "$2" ))?

    ((...))원래 명령처럼 0이나 1을 반환할 필요가 없나요 ?test

답변1

()명령을 그룹화하고 하위 쉘을 생성하는 연산자는 무엇 입니까?

아니요, 문서에서는 다음을 사용하여 표현식을 그룹화하는 연산자를 참조합니다 test.

test 0 -eq 0 -a \( 0 -eq 1 -o 1 -eq 1 \)

더 이상 사용되지 않는 경우 대체품은 무엇입니까?

대체 명령은 ()및 이며 {}, 이는 쉘 수준에서 유사하게 명령을 그룹화합니다.

test 0 -eq 0 && (test -0 -eq 1 || test 1 -eq 1)
test 0 -eq 0 && { test -0 -eq 1 || test 1 -eq 1; }

패턴을 보는 것은 쉽습니다. testfor 표현식에 사용된 모든 연산자는 셸에서 해당 for 명령으로 대체됩니다.

test "$1" -a "$2"로 교체해야 할까요 test "$1" && test "$2", 아니면 로 교체해야 할까요 (( test "$1" && test "$2" ))?

산술 표현식을 평가하는 것이 목적이므로 명령의 종료 상태에 관계없이 산술 확장을 위해 test "$1" && test "$2"; 로 바꿔야 합니다 . (())예를 들어 다음은 유효합니다.

(( $(test 1 -eq 1 && echo $?) && $(test 0 -eq 0 && echo $?) ))

0(명령 대체에 유의하십시오 . 내부 명령의 종료 상태로 대체되며 0평가된 표현식은 실제로 입니다 (( 0 && 0 )).)

그러나 이로 인해 구문 오류가 발생합니다.

(( test 1 -eq 1 && test 0 -eq 0 ))
$ (( test 1 -eq 1 && test 0 -eq 0 ))
bash: ((: test 1 -eq 1 && test 0 -eq 0 : syntax error in expression (error token is "1 -eq 1 && test 0 -eq 0 ")

답변2

더 간단한 언어로 매우 중요한 사실을 강조하려면 다음을 수행하십시오.

화면에 입력한 문자는 호출한 명령에 의해 "표시"(수신)될 수도 있고 그렇지 않을 수도 있습니다. 당신은 아마도 무언가를 인용할 때마다 이런 일이 발생한다는 사실에 익숙할 것입니다.

이것껍데기입력하는 모든 문자를 확인하세요. 쉘에는 이러한 문자를 처리하는 방법에 대한 자체 규칙이 있습니다. 예를 들어, 이 echo명령은 다음의 각 인스턴스에서 정확히 동일한 내용을 "확인"합니다.

$ echo hello
hello
$ echo "hello"
hello
$ echo 'hello'
hello
$ echo \h\e\l\l\o
hello
$ echo 'h'"e"\l$'lo'
hello
$ somevar=hello;echo $somevar
hello
$ somevar='h'"el"\l\o;echo $somevar
hello
$ 

명령이 위의 따옴표와 백슬래시를 "인식"하지 않는 것처럼 echo쉘은 괄호를 구체적으로 처리합니다. 그래서,인용되지 않은 경우, 그들은 쉘 이외의 어떤 것에도 보이지 않습니다.

find좋은 예는 괄호를 다음과 같이 허용하는 명령입니다 .논쟁. 브래킷의 경우도착명령은 find쉘에서 특별히 해석되지 않으므로 쉘에서 특별한 의미를 제거하려면 인용하거나 이스케이프해야 합니다. 따옴표와 이스케이프는아니요도달 find명령; 괄호만 사용 가능:

(에서또 다른 문제이 사이트에서 :)

# What you type:
find ~ \( -type f '-ex'ec ch\mod 600 {} + ')' -o \
       "(" -type d -exec c"hmo"d 700 {} ';' \)
# What the find command sees:
/home/tim ( -type f -exec chmod 600 {} + ) -o ( -type d -exec chmod 700 {} ; )
# If you typed this...
find ~ \( -type f -exec chmod 600 {} + ) -o \
       \( -type d -exec chmod 700 {} + \)
# ...find doesn't see anything, because bash runs into an error condition
# before it can even parse the line.  That close paren is special to bash.

이와 관련된 속어도 있습니다. 명령에서 특수 문자(일반적으로 작은따옴표 또는 큰따옴표, 백슬래시나 공백 문자도 포함될 수 있음)를 "표시"하려고 하는데 인용 및 이스케이프의 버그로 인해 해당 명령이 해당 문자를 볼 수 없는 경우 다음과 같이 말합니다. 쉘은 참조를 "먹습니다".

인용문 먹기(및 이를 둘러싼 어려움)의 흥미로운 예에는 원격 서버에 로그인하고 bash 세션을 시작한 다음 명령을 실행하여 sed파일에 저장된 파일을 수정하여 올바르게 참조되도록 하는 ssh 명령을 작성하는 것이 포함됩니다. 메시지의 HTTP에 포함됩니다.


그렇다면 짧은 대답은 다음과 같습니다.

  1. "'(' 및 ')' 연산자는 더 이상 사용되지 않는 것으로 표시되었습니다."

명령을 그룹화하고 하위 쉘을 생성하는 ( 및 ) 연산자입니까?

더 이상 사용되지 않는 경우 대체품은 무엇입니까?

괄호는 여전히 셸에서 특별한 의미를 가지며 쓸모가 없습니다. 더 이상 사용되지 않는 것은 괄호를 명령에 전달하는 것입니다 test(쉘이 괄호를 먹는 것을 방지하기 위해 인용하여).


*이것은 분명히 "재미"에 대한 정의에 따라 달라집니다.

관련 정보