파일 글로빙 패턴(!(*예))은 bash 쉘에서와 bash 스크립트에서 다르게 동작합니다.

파일 글로빙 패턴(!(*예))은 bash 쉘에서와 bash 스크립트에서 다르게 동작합니다.

다음은 bash 터미널에 직접 붙여 넣으면 작동합니다(bash를 명시적으로 호출합니다. bash 버전:) 4.4.19(1)-release (x86_64-pc-linux-gnu).

for filename in /home/dean/Downloads/!(*example).txt; do
    echo "${filename}"
done

이 명령은 파일 이름에 'example'이 없는 모든 txt 파일을 다시 에코합니다.

그러나 이것을 호출하는 스크립트로 변환 temp.sh하고 chmod +x temp.sh다음과 같이 호출 하면 ./temp.sh:

#!/usr/bin/env bash

for filename in /home/dean/Downloads/!(*example).txt; do
    echo "${filename}"
done

다음 오류가 발생합니다.

dean@dean-thinkpad-p52s:~/Downloads$ ./temp.sh 
./temp.sh: line 3: syntax error near unexpected token `('
./temp.sh: line 3: `for filename in /home/dean/Downloads/!(*example).txt; do'

나는 여기서 문제를 이해하지 못합니다. 쉘에서는 내가 원하는 것을 정확하게 수행하지만 스크립트에서는 수행하지 않는 이유는 무엇입니까?

편집 (답변판키님의 질문):

env쉘/터미널에서 호출되는 시점과 env쉘/스크립트에서 호출되는 시점 의 차이점은 다음과 같습니다 .

dean@dean-thinkpad-p52s:~/Downloads$ diff example_myshell.txt example_called_script.txt 
5a6
> _=/usr/bin/env
36,37d36
< TERM=xterm-256color
< SHELL=/bin/bash
38a38,39
> SHELL=/bin/bash
> TERM=xterm-256color
45c46
< PYENV_SHELL=bash
---
> SHLVL=4
47c48
< SHLVL=3
---
> PYENV_SHELL=bash
61d61
< _=/usr/bin/env

답변1

Korn 쉘 확장 연산자는 옵션 을 켠 경우 !(...)에만 사용할 수 있습니다 (기본적으로 꺼져 있음).bashextglob

extglob또는 다른 초기화 파일을 통해 대화형 셸을 켰을 수도 있지만 ~/.bashrc스크립트를 실행할 때 해당 파일이 제공되지 않으며 해당 옵션은 호출 셸에서 상속되지 않습니다( BASHOPTS환경의 변수가 아닌 한 거기에 두는 것은 나쁜 생각입니다).

명시적으로 켜기

shopt -s extglob

스크립트 시작 부분에서 작동해야 합니다.

shopt -s extglob아직 구문 분석되지 않은 다음 줄부터 시작하는 효과만 있습니다 . 즉, 하위 쉘에서만 확장 패턴을 켜기 위해 shopt -s extgloblike 를 사용할 수 없습니다.set -f

# this won't work
(
  shopt -s extglob
  echo !(no such file)
)

다음과 같은 작업을 수행해야 합니다.

(
  shopt -s extglob
  eval 'echo !(no such file)'
)

관련 정보