!(*.sh) はコマンドラインでは機能しますが、スクリプトでは機能しません。

!(*.sh) はコマンドラインでは機能しますが、スクリプトでは機能しません。

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_ENVBashは指定されたファイルを読み込みますが、それに依存しないことをお勧めします。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)

関連情報