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 쉘 스프레드 연산자는 이 옵션을 켠 경우에만 사용할 수 있습니다 !(...)
(기본적으로 꺼져 있음).bash
extglob
extglob
대화형 셸에서 다른 초기화 파일을 전달했거나 열었을 수 있지만 ~/.bashrc
이러한 파일은 스크립트를 실행할 때 가져오지 않으며 옵션은 호출 셸에서 상속되지 않습니다( BASHOPTS
환경에서 변수가 아닌 한). 거기에 두는 것은 나쁜 생각입니다).
명시적으로 열어라
shopt -s extglob
스크립트 시작 부분에서는 작동해야 합니다.
아직 구문 shopt -s extglob
분석되지 않은 다음 줄부터만 유효합니다. 이는 하위 쉘에서만 확장 모드를 켜기 위해 shopt -s extglob
like를 사용할 수 없음을 의미합니다 .set -f
# this won't work
(
shopt -s extglob
echo !(no such file)
)
다음과 같은 작업을 수행해야 합니다.
(
shopt -s extglob
eval 'echo !(no such file)'
)