foo*一致するファイル名のリストにそれを展開するのは実際にはシェルであるため、mvそれ自体で実行できることはほとんどないことを認識することが重要です。
ここでの問題は、globが一致しない場合、一部のシェルbash(および他のほとんどのBourneのようなシェル、70年代後半にBourneシェルによって実際に導入されたバグ)がパターンに逐語的にコマンドを渡すことです。
ときだからここに、foo*代わりにコマンドを中止する任意のファイルを、(前のBourneシェルおよびいくつかの近代的なシェルが行うように)一致していない、シェルはそのまま渡しfoo*にファイルをmvので、基本的に求めて、mvという名前のファイルを移動することfoo*。
そのファイルは存在しません。一致した場合、実際にパターンに一致したはずなのでmv、エラーを報告します。パターンがfoo[xy]代わりにあった場合、とファイルの代わりにmv呼び出されたファイルを誤って移動していた可能性があります。foo[xy]fooxfooy
さて、その問題のないシェル(Bourne、csh、tcsh、fish、zsh、bash -O failglob)でも、エラーが発生しますmv foo* ~/barが、今回はシェルによってエラーが発生します。
一致するファイルがない場合はエラーではなく、foo*その場合は何も移動しないと見なしたい場合は、最初にファイルのリストを作成します(nullglobオプションを使用するなどのエラーを引き起こさない方法で)いくつかのシェル)、そして唯一の呼び出しmvはリストが空でないことです。
他の理由で失敗したかのように(追加するように)すべてのエラーを非表示にするよりも、おそらく理由を知りたいと思うでしょう。mv2> /dev/nullmv
zshで
files=(foo*(N)) # where the N glob qualifier activates nullglob for that glob
(($#files == 0)) || mv -- $files ~/bar/
または、匿名関数を使用して、一時変数の使用を避けます。
() { (($# == 0)) || mv -- "$@" ~/bar/; } foo*(N)
zshBourneバグがないシェルの1つであり、globが一致しない場合(およびnullglobオプションが有効になっていない場合)にコマンドを実行せずにエラーを報告するため、ここで、zshエラーを非表示にして復元できますstderrの場合mv、mvエラーがあれば表示されますが、一致しないグロブに関するエラーは表示されません。
(mv 2>&3 foo* ~/bar/) 3>&2 2>&-
またはzargs、foo*globがあまりにもmanファイルに展開される場合に、これを使用して問題を回避することもできます。
autoload zargs # best in ~/.zshrc
zargs -r -- foo* -- mv -t ~/bar # here assuming GNU mv for its -t option
ksh93の場合:
files=(~(N)foo*)
((${#files[#]} == 0)) || mv -- "${files[@]}" ~/bar/
bashの場合:
bashnullglob1つのglobのみを有効にする構文はありません。failglobオプションはキャンセルされるnullglobため、次のようなものが必要になります。
saved=$(shopt -p nullglob failglob) || true
shopt -s nullglob
shopt -u failglob
files=(foo*)
((${#files[@]} == 0)) || mv -- "${files[@]}" ~/bar/
eval "$saved"
または、サブシェルでオプションを設定して保存する必要があり、それらを前に保存し、後で復元する必要があります。
(
shopt -s nullglob
shopt -u failglob
files=(foo*)
((${#files[@]} == 0)) || mv -- "${files[@]}" ~/bar/
)
に yash
(
set -o nullglob
files=(foo*)
[ "${#files[@]}" -eq 0 ] || mv -- "${files[@]}" ~/bar/
)
に fish
フィッシュシェルでは、nullglobの動作がsetコマンドのデフォルトであるため、次のようになります。
set files foo*
count $files > /dev/null; and mv -- $files ~/bar/
POSIXly
nullglobPOSIXにはオプションがshなく、定位置パラメーター以外の配列はありません。ただし、グロブが一致したかどうかを検出するために使用できるトリックがあります。
set -- foo[*] foo*
if [ "$1$2" != 'foo[*]foo*' ]; then
shift
mv -- "$@" ~/bar/
fi
a foo[*]とfoo*globの両方を使用することにより、一致するファイルがない場合と、たまたま呼び出されるfoo*(set -- foo*できなかった)ファイルが1つある場合を区別できます。
もっと読む:
mv foo* ~/bar/ 2> /dev/null?