Синтаксическая ошибка рядом с неожиданным токеном `('


11

Когда я использую код ниже в терминале Ubuntu, он работает нормально:

rm !(*.sh) -rf

Но если я помещаю тот же строчный код в скрипт оболочки (clean.sh) и запускаю скрипт оболочки из терминала, он выдаст ошибку:

скрипт clean.sh:

#!/bin/bash
rm !(*.sh) -rf

Я получаю ошибку:

./clean.sh: line 2: syntax error near unexpected token `('
./clean.sh: line 2: `rm !(*.sh) -rf'

вы можете помочь?


Ответы:


23

rm !(*.sh)это extglobсинтаксис, который означает удалить все файлы, кроме тех, которые имеют .shрасширение.

В вашем интерактивном bashэкземпляре опция оболочки включена extglob:

$ shopt extglob 
extglob         on

Теперь, когда ваш скрипт выполняется в подоболочке, вам нужно включить extglobего, добавив в начале скрипта:

shopt -s extglob

Итак, ваш скрипт выглядит так:

#!/bin/bash
shopt -s extglob
rm -rf -- !(*.sh)

РЕДАКТИРОВАТЬ :

Чтобы удалить все файлы, кроме .shрасширенных, используйте GLOBIGNORE(поскольку вы не хотите включать extglob):

#!/bin/bash
GLOBIGNORE='*.sh'
rm -rf *

Пример :

$ ls -1
barbar
bar.sh
egg
foo.sh
spam

$ GLOBIGNORE='*.sh'

$ rm *

$ ls -1
bar.sh
foo.sh

Могу ли я изменить свою команду, которая делает то же самое без запуска этого? shopt -s extglob?
Тал

@Tal проверь мои правки ..
Heemayl

1
спасибо :) (переполнение стека заставляет меня написать 15 символов в комментарии :( :( :()
Tal

но тут есть два хороших ответа!
Тал

1
Это должен быть принятый ответ, поскольку он фактически отвечает на вопрос, в то время как другой просто описывает обходной путь.
Гунтрам Блом поддерживает Монику

4

Хорошо, это кросс-пост, но я должен написать ответ. ;)

Вы могли бы использовать findвместо

find . -maxdepth 1 ! -name '*.sh' -exec rm -rf {} \;

2

Вам необходимо включить extglob:

shopt -s extglob

1
@ Pilot6: видите man bash. Это позволяет расширенное сглаживание как !(...).
Чороба

Могу ли я изменить свою команду, которая делает то же самое без запуска этого? shopt -s extglob
Тал
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.