Bunun foo*, eşleşen dosya adları listesine genişleyen bir kabuk olduğunun farkına varmak önemlidir , bu nedenle çok az şey mvyapılabilir.
Buradaki sorun, bir glob eşleşmediğinde, bazı kabukları bash(ve diğer Bourne benzeri kabukları, buggy davranışının aslında Bourne kabuğunun 70'li yılların sonlarında getirdiği gibi) komutları vermesidir.
Yani burada, foo*herhangi bir dosyayla eşleşmediğinde, komutu iptal etmek yerine (Bourne öncesi kabukları ve birkaç modern kabuğun yaptığı gibi), kabuk sözde bir foo*dosyayı geçirir mv, bu nedenle temelde mvçağrılan dosyayı taşımak ister foo*.
Bu dosya mevcut değil. Olsaydı, aslında kalıpla eşleşirdi, bu yüzden mvbir hata bildirdi. Desen foo[xy]yerine, olsaydı , mvyanlışlıkla ve dosyaları foo[xy]yerine adlı bir dosyayı yanlışlıkla taşıyabilirdi .fooxfooy
Şimdi, bu problemi olmayan kabuklarda bile (Bourne öncesi, csh, tcsh, balık, zsh, bash -O failglob öncesi), yine de bir hata ile karşı karşıya kalırsınız mv foo* ~/bar, ama bu sefer kabuktan.
Eğer bir dosya eşleşmesi yoksa bir hata olmadığını düşünmek istiyorsan foo*ve bu durumda bir şeyi taşımazsan, ilk önce dosyaların listesini (bu nullglobseçeneği kullanarak hataya neden olmayacak şekilde) oluşturmak istersin . Bazı mermiler) ve sonra sadece arama mv, liste boş değildir.
Bu, başka bir nedenden ötürü başarısız olmuş gibi (ekleme gibi) tüm hataları gizlemekten daha iyidir , muhtemelen nedenini bilmek istersiniz.mv2> /dev/nullmv
zsh içinde
files=(foo*(N)) # where the N glob qualifier activates nullglob for that glob
(($#files == 0)) || mv -- $files ~/bar/
Veya geçici bir değişken kullanmamak için isimsiz bir işlev kullanın:
() { (($# == 0)) || mv -- "$@" ~/bar/; } foo*(N)
zshBourne böceğine sahip olmayan ve bir glob eşleşmediğinde (ve nullglobseçenek etkinleştirilmemişse) komutu çalıştırmadan hata bildiren kabuklardan biridir, bu yüzden burada zshhatayı gizleyip geri yükleyebilirsiniz. stderr bunun için mvhala mvvarsa hataları görürsünüz , fakat eşleşmeyen glob'larla ilgili hatayı görmezsiniz:
(mv 2>&3 foo* ~/bar/) 3>&2 2>&-
Veya zargseğer dünya foo*çok fazla erkek dosyaya da yayılırsa, problemleri de önleyebilecek olanları kullanabilirsiniz.
autoload zargs # best in ~/.zshrc
zargs -r -- foo* -- mv -t ~/bar # here assuming GNU mv for its -t option
Ksh93’de:
files=(~(N)foo*)
((${#files[#]} == 0)) || mv -- "${files[@]}" ~/bar/
Bash:
bashnullglobyalnızca bir glob için etkinleştirilecek sözdizimine sahip değildir ve failglobseçenek iptal eder, nullglobböylece aşağıdaki gibi şeylere ihtiyacınız olur:
saved=$(shopt -p nullglob failglob) || true
shopt -s nullglob
shopt -u failglob
files=(foo*)
((${#files[@]} == 0)) || mv -- "${files[@]}" ~/bar/
eval "$saved"
veya kaydetmek için alt kabuktaki seçenekleri ayarlayın, daha önce kaydetmeniz ve sonra geri yüklemeniz gerekir.
(
shopt -s nullglob
shopt -u failglob
files=(foo*)
((${#files[@]} == 0)) || mv -- "${files[@]}" ~/bar/
)
İçinde yash
(
set -o nullglob
files=(foo*)
[ "${#files[@]}" -eq 0 ] || mv -- "${files[@]}" ~/bar/
)
İçinde fish
Balık kabuğunda nullglob davranışı setkomut için varsayılandır , bu yüzden sadece:
set files foo*
count $files > /dev/null; and mv -- $files ~/bar/
POSIXly
Hiçbir var nullglobPOSIX'deki seçenek shve konumsal parametreler dışında hiçbir dizi. Bir kürenin eşleşip eşleşmediğini tespit etmek için kullanabileceğiniz bir numara var:
set -- foo[*] foo*
if [ "$1$2" != 'foo[*]foo*' ]; then
shift
mv -- "$@" ~/bar/
fi
A ikisini kullanarak foo[*]ve foo*topak, hiçbir eşleme dosyası ve adı olur bir dosya var bir tane var durumda ayırt edebilir foo*(a hangi set -- foo*yapamadı).
Daha fazla okuma:
mv foo* ~/bar/ 2> /dev/null?