파일 일치 패턴 !(*예제)은 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)'
)

관련 정보