O comando funciona no terminal, mas não no script bash [duplicado]

3

Se eu quiser excluir tudo no diretório atual, exceto "myfile", posso usar

rm -r !("myfile")

Mas se eu colocar isso em um script (chamado cleanup ):

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

Eu recebo:

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

Se eu correr

ps -p $$

Eu posso ver que meu terminal está usando bash,

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

então não estou claro qual é o problema.

Notas:

  1. Eu percebo que se o script realmente funcionasse, ele se excluiria. Então, meu script realmente seria algo mais parecido com: rm -r !("cleanup"|"myfile") , mas a mensagem de erro é a mesma.
  2. Como mostrado pelo blockquote, isso está em um sistema operacional Raspbian (9-stretch), que é baseado no Debian.
  3. Eu sinto que esta questão está fadada a ser uma duplicata, mas não consigo encontrá-la. Há um nome semelhante questionar , mas é no que diz respeito a herdar variáveis, e por isso não resolve o meu problema.
por Blair Fonville 07.09.2018 / 19:38

2 respostas

6

O padrão !(pattern-list) é um balão estendido . Muitas distros têm habilitado para shells interativos, mas não para shells não interativos. Você pode verificar isso com

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

Para corrigir seu script, você precisa ativá-lo: add

shopt -s extglob

no começo dele.

    
por 07.09.2018 / 20:02
4

Você está usando aqui um recurso de globbing ampliado.

Na página 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

Esta opção shell que pode ser controlada através do comando shopt é por padrão ativada em shells interativos, mas desativada por padrão em shells não-interativas (scripts).

Para ativar, use shopt -s extglob .

    
por 07.09.2018 / 20:02