O parêntese funciona no próprio shell bash, mas não no script bash

10

Como o título diz, posso executar este comando a partir do prompt da linha de comando:

cp -r folder/!(exclude-me) ./

Para copiar recursivamente todo o conteúdo de folder exceto para o subdiretório chamado exclude-me no diretório atual. Isso funciona exatamente como pretendido. No entanto, eu preciso disso para trabalhar em um script bash que eu escrevi, onde eu tenho isso:

if [ -d "folder" ]; then
  cp -r folder/!(exclude-me) ./
  rm -rf folder
fi

Mas quando eu executo o script:

bash my-script.sh

Eu entendo isso:

my-script.sh: line 30: syntax error near unexpected token '('
my-script.sh: line 30: '  cp -r folder/!(exclude-me) ./'

E não sei por que funciona no prompt de comando, mas a mesma linha não funciona em um script bash.

    
por nzifnab 25.09.2014 / 20:20

2 respostas

7

Isso porque a sintaxe que você está usando depende de um recurso bash específico que não é ativado por padrão para shells não-interativos (scripts). Você pode ativá-lo adicionando o comando relevante ao seu script:

## Enable extended globbing features
shopt -s extglob

if [ -d "folder" ]; then
  cp -r folder/!(exclude-me) ./
  rm -rf folder
fi

Esta é a seção relevante de man bash :

   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 fol‐
   lowing sub-patterns:

          ?(pattern-list)
                 Matches zero or one occurrence of the given patterns
          *(pattern-list)
                 Matches zero or more occurrences of the given patterns
          +(pattern-list)
                 Matches one or more occurrences of the given patterns
          @(pattern-list)
                 Matches one of the given patterns
          !(pattern-list)
                 Matches anything except one of the given patterns
    
por 25.09.2014 / 20:24
1

Adicione esta linha perto do topo do seu script:

shopt -s extglob

!(...) é um recurso de correspondência estendida de padrões, você precisa de extglob option enable para usá-lo. Consulte shopt para obter mais detalhes.

    
por 25.09.2014 / 20:22