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