Błąd składni w pobliżu nieoczekiwanego tokena `('

11

Kiedy używam poniższego kodu w terminalu Ubuntu, działa dobrze:

rm !(*.sh) -rf

Ale jeśli umieszczę ten sam kod wiersza w skrypcie powłoki (clean.sh) i uruchomię skrypt powłoki z terminala, generuje błąd:

skrypt clean.sh:

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

Otrzymuję błąd:

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

możesz pomóc?

Tal
źródło

Odpowiedzi:

23

rm !(*.sh)to extglobskładnia, która oznacza usunięcie wszystkich plików oprócz tych, które mają .shrozszerzenie.

W interaktywnym bashwystąpieniu opcja powłoki extglobjest włączona:

$ shopt extglob 
extglob         on

Teraz, gdy skrypt działa w podpowłoce, musisz włączyć extglob, dodając to na początku skryptu:

shopt -s extglob

Twój skrypt wygląda więc tak:

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

EDYTOWAĆ :

Aby usunąć wszystkie pliki oprócz .shtych rozszerzających, użyj GLOBIGNORE(ponieważ nie chcesz włączać extglob):

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

Przykład:

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

$ GLOBIGNORE='*.sh'

$ rm *

$ ls -1
bar.sh
foo.sh
heemayl
źródło
czy mogę zmienić polecenie, które robią to samo bez uruchamiania tego? shopt -s extglob?
Tal
@Tal sprawdź moje zmiany ..
heemayl
1
dzięki :) (przepełnienie stosu zmusza mnie do napisania 15 znaków w komentarzu :( :( :()
Tal
ale tutaj są dwie dobre odpowiedzi!
Tal
1
To powinna być zaakceptowana odpowiedź, ponieważ faktycznie odpowiada na pytanie, podczas gdy druga opisuje tylko obejście.
Guntram Blohm obsługuje Monikę
4

Ok, to jest cross-post, ale muszę napisać odpowiedź. ;)

Możesz findzamiast tego użyć

find . -maxdepth 1 ! -name '*.sh' -exec rm -rf {} \;
AB
źródło
2

Musisz włączyć extglob:

shopt -s extglob
choroba
źródło
1
@ Pilot6: Patrz man bash. Umożliwia rozszerzone globowanie jak !(...).
choroba
czy mogę zmienić polecenie, które robią to samo bez uruchamiania tego? shopt -s extglob
Tal