私は現在非常に単純なzshスクリプトを書いています。私が通常することは次のとおりです。
mv */*.{a,b} .
zshスクリプトで実行すると、サイズが異なるように調整され、インタラクティブモードで作業すると失敗します。
% mkdir dir
% touch dir/file.a
% ls file.a
ls: cannot access file.a: No such file or directory
% mv */*.{a,b} .
% ls file.a
file.a
したがって、これはうまくいきますが、スクリプトでは次のようになります。
% mkdir dir
% touch dir/file.a
% ls file.a
ls: cannot access file.a: No such file or directory
% cat script.sh
#!/usr/bin/zsh
mv */*.{a,b} .
% ./script.sh
./script.sh:2: no matches found: */*.b
では、違いは何ですか?私は何が間違っていましたか?
ベストアンサー1
両方のデフォルトオプション設定が正しくありませんzsh
。代わりにasコマンドを使用すると、echo
何が起こっているのかを簡単に確認できますmv
。
null_glob
インタラクティブにオプションを設定したようです。zsh
ドキュメントによると、このオプションはデフォルトでは設定されていません。このオプションをオフにするとどうなりますか?nomatch
他のオプションが設定されているかどうかによって異なります。nomatch
unset( ) を使用すると、nonomatch
次のような結果が得られます。
% mkdir dir
% touch dir/file.a
% ls file.a
ls: cannot access file.a: No such file or directory
% echo */*.{a,b} .
dir/file.a */*.b .
拡張は2つの段階で行われます。まず、*/*.{a,b}
2 単語に拡張します。*/*.a
and */*.b
。その後、各単語はグローバルパターンに展開されます。最初のものdir/file.a
は一致するものがないため、2番目のものは独自に拡張され、2番目のものは独自に拡張されます。これが意味するのは、mv
and not を使用する場合は、echo
2 つのファイル (音) と (該当ファイルなし) をmv
移動しなければならないということです。これは、などのほとんどのシェルでデフォルトで発生します。dir/file.a
*/*.b
sh
ksg
bash
zsh デフォルトオプションの設定はnull_glob
設定されずにnomatch
設定されます。スクリプトはデフォルトのオプション設定で実行されます(実際に~/.zshenv
変更しないでください、または変更/etc/zshenv
しない限り)。これはスクリプトから次のことを意味します。
% mkdir dir
% touch dir/file.a
% ls file.a
ls: cannot access file.a: No such file or directory
% cat script.sh
#!/usr/bin/zsh
echo */*.{a,b} .
% ./script.sh
./script.sh:2: no matches found: */*.b
一致するものがないため、*/*.b
エラーが発生しますnomatch
。
/ commandの前にスクリプトを挿入すると、上記のsetopt nonomatch
誤った動作に戻ります。存在しないファイルを移動しようとします。echo
mv
/コマンドの前にスクリプトを挿入すると、setopt null_glob
有効なインタラクティブシェルから得られる動作が得られます。echo
mv