यह महसूस करना महत्वपूर्ण है कि यह वास्तव में शेल है जो कि foo*फ़ाइल नामों के मिलान की सूची में फैलता है , इसलिए थोड़ा mvही कर सकता है।
यहाँ समस्या यह है कि जब एक ग्लोब मेल नहीं खाता है, तो कुछ गोले bash(और अधिकांश अन्य बॉर्न-जैसे गोले, कि बुग्गी व्यवहार वास्तव में 70 के दशक के अंत में बॉर्न शेल द्वारा पेश किया गया था) कमांड को पैटर्न वर्बेटिम पास करते हैं।
इसलिए यहाँ, जब foo*कमांड को निरस्त करने के बजाय किसी भी फाइल से मेल नहीं खाता है (जैसे पूर्व बॉर्न शेल और कई आधुनिक गोले करते हैं), शेल एक वर्बेटिम foo*फ़ाइल को पास करता है mv, इसलिए मूल रूप mvसे कॉल की गई फ़ाइल को स्थानांतरित करने के लिए कहता है foo*।
वह फ़ाइल मौजूद नहीं है। यदि ऐसा होता है, तो यह वास्तव में पैटर्न से मेल खाता है, इसलिए mvएक त्रुटि की रिपोर्ट करता है। यदि पैटर्न foo[xy]इसके बजाय था, mvतो गलती से फ़ाइल और फ़ाइलों के foo[xy]बजाय एक फ़ाइल को स्थानांतरित कर सकता था ।fooxfooy
अब, उन गोले में भी, जिसमें वह समस्या नहीं है (पूर्व-बॉर्न, csh, tsh, मछली, 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)
zshउन गोले में से एक है जिनके पास बॉर्न बग नहीं है और एक कमांड को निष्पादित किए बिना एक त्रुटि की रिपोर्ट करते हैं जब एक ग्लोब मेल नहीं खाता (और nullglobविकल्प सक्षम नहीं किया गया है), तो यहां, आप zshत्रुटि को छिपा सकते हैं और पुनर्स्थापित कर सकते हैं stderr के लिए mvताकि आप अभी भी देखना होगा mvत्रुटियों यदि कोई हो, लेकिन नहीं मेल नहीं खाने वाले globs के बारे में त्रुटि:
(mv 2>&3 foo* ~/bar/) 3>&2 2>&-
या आप उपयोग कर सकते हैं zargsजो समस्याओं से भी foo*बचेंगे यदि ग्लोब बहुत आदमी फ़ाइलों तक विस्तारित होगा।
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/
बैश में:
bashnullglobकेवल एक ग्लोब के लिए सक्षम करने के लिए कोई सिंटैक्स नहीं है , और 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
मछली के खोल में, नलग्लोब व्यवहार 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
दोनों foo[*]और foo*ग्लोब का उपयोग करके , हम उस मामले के बीच अंतर कर सकते हैं जहां कोई मिलान फ़ाइल नहीं है और जिस पर एक फ़ाइल है जिसे कॉल किया जाता है foo*(जो set -- foo*ऐसा नहीं कर सकता)।
अधिक पढ़ने:
mv foo* ~/bar/ 2> /dev/null?