Parantez bash kabuğunun kendisinde çalışır, ancak bash komut dosyasında çalışmaz


11

Bu komutu komut satırı istemimden çalıştırabilirim:

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

Geçerli dizine adlandırılan alt dizin folder dışındaki tüm içeriğini özyinelemeli olarak kopyalamak için exclude-me. Bu tam olarak tasarlandığı gibi çalışır. Ancak, ben bu var, ben yazdığım bir bash komut dosyası çalışmak için buna ihtiyacım var:

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

Ama senaryoyu çalıştırdığımda:

bash my-script.sh

Bunu anladım:

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

Ve neden komut isteminden çalıştığına dair bir kaybım var, ancak aynı satır bir bash komut dosyasında çalışmıyor.

Yanıtlar:


11

Çünkü kullandığınız sözdizimi, etkileşimli olmayan kabuklar (komut dosyaları) için varsayılan olarak etkinleştirilmeyen belirli bir bash özelliğine bağlıdır. Komut dosyanıza ilgili komutu ekleyerek etkinleştirebilirsiniz:

## Enable extended globbing features
shopt -s extglob

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

Bu, ilgili bölümdür 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

Bu cevabı ikinci kez buldum (evet, kötü hafıza). Bu sefer env > file1senaryoyu çalıştırıp çalıştırmayı denedim ./itve sonra env > file2ve s'de source itbir fark bulacağım umuduyla env, durum böyle değil. İki kabuk arasındaki tüm farkı programlı olarak nasıl listeleyebilirim (bu durumda etkileşimli ve etkileşimli olmayan)?
Enrico Maria De Angelis


2

Bu satırı komut dosyanızın üstüne yakın bir yere ekleyin:

shopt -s extglob

!(...)gelişmiş bir desen eşleme özelliğidir, extglobkullanmak için seçenek etkinleştirmeniz gerekir. Daha fazla bilgi için shopt yerleşik bölümüne bakınız.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.