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?


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

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 {} \;

2

Musisz włączyć extglob:

shopt -s extglob

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.