Bunun foo*
, eşleşen dosya adları listesine genişleyen bir kabuk olduğunun farkına varmak önemlidir , bu nedenle çok az şey mv
yapı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 mv
bir hata bildirdi. Desen foo[xy]
yerine, olsaydı , mv
yanlışlıkla ve dosyaları foo[xy]
yerine adlı bir dosyayı yanlışlıkla taşıyabilirdi .foox
fooy
Ş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 nullglob
seç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.mv
2> /dev/null
mv
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)
zsh
Bourne böceğine sahip olmayan ve bir glob eşleşmediğinde (ve nullglob
seçenek etkinleştirilmemişse) komutu çalıştırmadan hata bildiren kabuklardan biridir, bu yüzden burada zsh
hatayı gizleyip geri yükleyebilirsiniz. stderr bunun için mv
hala mv
varsa 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 zargs
eğ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:
bash
nullglob
yalnızca bir glob için etkinleştirilecek sözdizimine sahip değildir ve failglob
seçenek iptal eder, nullglob
bö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ışı set
komut için varsayılandır , bu yüzden sadece:
set files foo*
count $files > /dev/null; and mv -- $files ~/bar/
POSIXly
Hiçbir var nullglob
POSIX'deki seçenek sh
ve 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
?