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

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'

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

Tal
источник

Ответы:

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
heemayl
источник
Могу ли я изменить свою команду, которая делает то же самое без запуска этого? shopt -s extglob?
Тал
@Tal проверь мои правки ..
Heemayl
1
спасибо :) (переполнение стека заставляет меня написать 15 символов в комментарии :( :( :()
Tal
но тут есть два хороших ответа!
Тал
1
Это должен быть принятый ответ, поскольку он фактически отвечает на вопрос, в то время как другой просто описывает обходной путь.
Гунтрам Блом поддерживает Монику
4

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

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

find . -maxdepth 1 ! -name '*.sh' -exec rm -rf {} \;
AB
источник
2

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

shopt -s extglob
choroba
источник
1
@ Pilot6: видите man bash. Это позволяет расширенное сглаживание как !(...).
Чороба
Могу ли я изменить свою команду, которая делает то же самое без запуска этого? shopt -s extglob
Тал