복합 명령에서 bash 옵션 설정

복합 명령에서 bash 옵션 설정

extglob복합 화합물 내에서만 쉘 옵션을 설정하면 후속 확장 글로브가 실패하는 것으로 나타났습니다 . 복합 명령 외부에서 쉘 옵션을 설정해야 합니까? Bash 매뉴얼 페이지에서는 그러한 요구 사항에 대한 표시를 보지 못했습니다.

예를 들어 다음 스크립트는 제대로 작동합니다(인쇄 a.0 a.1).

#!/bin/bash
touch a.0   a.1 \
      a.b.0 a.b.1
shopt -s extglob
ls "a."!(b*)

그러나 마지막 두 줄을 복합 명령으로 실행하면 다음 오류와 함께 스크립트가 실패합니다.

syntax error near unexpected token `('
`    ls "a."!(b*)'

이는 4.2에서 4.4까지의 Bash 버전과 다양한 버전을 사용하여 테스트되었습니다.복합 명령:

(1) 조건부 --if

#!/bin/bash
touch a.0   a.1 \
      a.b.0 a.b.1
if true; then
    shopt -s extglob
    ls "a."!(b*)
fi

(2) 교정기 --{ }

#!/bin/bash
touch a.0   a.1 \
      a.b.0 a.b.1
{
    shopt -s extglob
    ls "a."!(b*)
}

(3) 서브쉘 -- ( ):

#!/bin/bash
touch a.0   a.1 \
      a.b.0 a.b.1
(
    shopt -s extglob
    ls "a."!(b*)
)

모든 경우에 shopt복합 명령 외부로 이동하면 스크립트가 성공합니다.

답변1

전체 명령이 구문 분석되기 전에는 복합 명령의 어떤 부분도 실행되지 않습니다.쉘 작업매뉴얼 섹션: 모든 토큰화 및 구문 분석은 "the" 명령이 실행되기 전에 발생합니다. 활성화하면 extglob토큰화 중에 인식되는 새로운 패턴 일치 연산자를 추가하여 언어 구문이 변경됩니다.

도달한 shopt시점에 명령이 실행되지 않았기 때문에 단일 항목으로 표시되기 보다는 시도된 기록 확장( ) 또는 제어 연산자 로 표시됩니다(및 히스토리 확장이 없다는 점을 제외하면 , 등에도 동일) . 거기).!(!(!(@(

구문 분석이 해당 토큰에 도달하면 일반적으로 두 경우 모두 오류가 발생하지만 !(...)줄 시작 부분이나 그 이후에는 time부정된 하위 쉘 파이프라인이 있습니다. " unexpected token `('"는 해당 지점에서 하위 쉘 표현식을 허용할 수 없음을 의미합니다.

서브셸에서 일시적으로만 extglob을 활성화하려는 경우 이는 다소 성가신 일입니다. 한 가지 해결 방법은 원하는 glob을 사용하는 함수를 정의한 다음 extglob을 다시 비활성화하고그 다음에extglob을 활성화하여 서브셸에서 함수를 호출합니다.

shopt -s extglob
f() { ls "a."!(b*) ; }
shopt -u extglob
(
    shopt -s extglob
    f
)

매우 투박합니다.


복합 명령 내에서 별칭을 생성하는 경우에도 동일한 효과가 발생합니다. 왜냐하면 별칭도 구문 분석 전에 처리되기 때문입니다.

if true
then
    alias foo=echo
    foo bar
fi
foo xyz

foo: command not found을 인쇄 한 다음 을 인쇄합니다 xyz. 왜냐하면 별칭이~이다생성되었지만 if완료될 때까지 사용할 수 없습니다.

관련 정보