Ubuntuの端末で次のコードを使用すると正常に動作します。
rm !(*.sh) -rf
ただし、同じコード行をシェルスクリプト(clean.sh
)に入れて端末でシェルスクリプトを実行すると、次のようにエラーが発生します。
clean.shスクリプト:
#!/bin/bash
rm !(*.sh) -rf
私が得るエラー:
./clean.sh: line 2: syntax error near unexpected token `('
./clean.sh: line 2: `rm !(*.sh) -rf'
助けてください?
答え1
以下を有効にする必要がありますextglob
。
shopt -s extglob
答え2
バッシュでは一部模様デフォルトでは有効になっていませんが、オプションを設定して有効にできます。shopt
。初期のUnixシェルには存在しなかったModes !(NOT-THIS)
、およびは後でkshに追加され、POSIXでは標準化されておらず、デフォルトでは認識されないため、最初に実行する必要があります@(THIS|THAT)
。*(ZERO-OR-MORE)
+(ONE-OR-MORE)
?(OPTIONAL)
shopt -s extglob
コマンドラインでこれらのモードを使用できます。これは、スクリプトではなく対話型シェルからのみshopt -s extglob
.fileを読み取ることができることを示します。.bashrc
(Bashがスクリプトの実行を開始するときに環境変数を設定した場合、BASH_ENV
Bashは指定されたファイルを読み込みますが、それに依存しないことをお勧めします。BASH_ENV
予想される値に設定されている場合にのみスクリプトが機能するためです。)指すファイルを変更しない場合にのみ)。
shopt -s extglob
スクリプトの上部の行の下に含めるだけです#!/bin/bash
。
答え3
シェルスクリプト方式
デフォルトでは、globはBASHスクリプトには影響しません(ただし、有効にすることはできますshopt
)。 BASH以外のインタプリタでシェルスクリプトを実行すると、globがまったく機能しない可能性があります。
このコマンドを使用すると、同じ効果が得られますfind
。これは私が推奨するものです(要件が増えるにつれてより多くの制御があるため)。
サイズに合わせて着てみてください:
find . -mindepth 1 -maxdepth 1 -not -iname "*.sh" -exec rm -rf {} \;
ファイルの生成方法
取ることができる別のアプローチは次のとおりです。
後でクリーンアップしたいタスクを実行する場合は、clean.sh、build.sh、install.shなどではなく、Makefileがそのタスクに適したツールかもしれません。
これは、レシピが常に順番に発生したり、出力を生成したレシピを常に再実行したくない場合に特に当てはまります。
同じことを行う単純なMakefileは次のとおりです。 (
前のスペースはrm
スクロールを作成する方法なので、タブでなければなりません。)
SOURCES := $(wildcard *.sh)
CLEAN_FILES := $(filter-out $(SOURCES),$(wildcard *))
CLEAN_FILES := $(filter-out Makefile,$(CLEAN_FILES))
build: $(SOURCES)
YOUR_RECIPE_HERE
clean:
rm -rf $(CLEAN_FILES)