)%EC%9D%80%20bash%20%EC%89%98%EC%97%90%EC%84%9C%EC%99%80%20bash%20%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%97%90%EC%84%9C%20%EB%8B%A4%EB%A5%B4%EA%B2%8C%20%EB%8F%99%EC%9E%91%ED%95%A9%EB%8B%88%EB%8B%A4..png)
다음은 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)'
)