括弧はbashシェル自体では機能しますが、bashスクリプトでは機能しません


11

このコマンドは、コマンドラインプロンプトから実行できます。

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

現在のディレクトリに指定されたサブディレクトリをfolder 除くすべての内容を再帰的にコピーしますexclude-me。これは意図したとおりに機能します。しかし、私が書いたbashスクリプトで作業するには、これが必要です。

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

しかし、スクリプトを実行すると:

bash my-script.sh

私はこれを手に入れます:

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

コマンドプロンプトから機能する理由がわかりませんが、bashスクリプトではまったく同じ行が機能しません。

回答:


11

これは、使用する構文が特定のbash機能に依存しているためです。この機能は、非インタラクティブシェル(スクリプト)ではデフォルトでアクティブ化されていません。スクリプトに関連するコマンドを追加することでアクティブ化できます。

## Enable extended globbing features
shopt -s extglob

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

これはの関連セクションです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

私がこの答えを見つけたのは2回目です(はい、不良メモリ)。この時間は、実行入れてみましたenv > file1スクリプトにして実行し./it、その後、env > file2source it、私は違いを発見しただろうと期待してenvそうではないの、。2つのシェルのすべての違いをプログラムで一覧表示するにはどうすればよいですか(この場合はインタラクティブと非インタラクティブ)。
エンリコマリアデアンジェリス


2

スクリプトの先頭近くに次の行を追加します。

shopt -s extglob

!(...)拡張パターンマッチング機能ですextglob。使用するには、オプションenable が必要です。詳細については、shopt builtinを参照してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.