명령은 터미널에서 작동하지만 bash 스크립트에서는 작동하지 않습니다.

명령은 터미널에서 작동하지만 bash 스크립트에서는 작동하지 않습니다.

"myfile"을 제외한 현재 디렉토리의 모든 항목을 삭제하려면 다음을 사용할 수 있습니다.

rm -r !("myfile")

cleanup하지만 스크립트( 라고 함 ) 에 넣으면 다음과 같습니다 .

#!/bin/bash
rm -r !("myfile")

나는 얻다:

pi@raspberrypi:~/tmp $ ./cleanup
./cleanup: line 2: syntax error near unexpected token `('
./cleanup: line 2: `rm -r !("file2")'

내가 달리면

ps -p $$

내 터미널이 bash를 사용하고 있는 것을 볼 수 있습니다.

 PID TTY          TIME CMD
1345 pts/3    00:00:02 bash

그래서 문제가 무엇인지 잘 모르겠습니다.


노트:

  1. 나는 깨달았다만약에스크립트는 실제로 작동하며 자체적으로 삭제됩니다. 따라서 내 스크립트는 실제로 다음과 비슷해 보이지만 rm -r !("cleanup"|"myfile")오류 메시지는 동일합니다.
  2. 블록 인용문에서 알 수 있듯이 이는 Debian 기반 Raspbian 운영 체제(9-stretch)입니다.
  3. 이 질문이 중복된 것 같은데 찾을 수 없습니다. 비슷한 이름이 있어요질문, 그러나 변수 상속에 관한 것이므로 문제가 해결되지 않습니다.

답변1

패턴은!(pattern-list)글로벌 확장. 많은 배포판에서는 대화형 쉘에서는 이를 활성화하지만 비대화형 쉘에서는 활성화하지 않습니다. 당신은 그것을 확인할 수 있습니다

$ shopt extglob
extglob         on
$ bash -c 'shopt extglob'
extglob         off

스크립트를 수정하려면 스크립트를 활성화해야 합니다: 추가

shopt -s extglob

그것의 시작 부분에.

답변2

여기서 사용하는 것은 확장된 와일드카드 기능입니다.

Bash man페이지에서:

If  the  extglob shell option is enabled using the shopt builtin, several extended pattern
matching operators are recognized.  In the following description, a pattern-list is a list
of  one  or more patterns separated by a |.  Composite patterns may be formed using one or
more of the following sub-patterns:   

[...]

       !(pattern-list)
              Matches anything except one of the given patterns

이 명령 제어 가능 셸 옵션은 shopt대화형 셸에서는 기본적으로 활성화되어 있지만 비대화형 셸(스크립트)에서는 기본적으로 비활성화되어 있습니다.

활성화하려면 를 사용하세요 shopt -s extglob.

관련 정보