पहले मैं एक परीक्षण आधार बनाऊंगा - 5 फाइलें और एक फ़ोल्डर:
touch file1 file2 file3 file4 file5
mkdir folder
आगे मैं एक टेस्ट कमांड चलाऊंगा। -v
विकल्प निर्दिष्ट करता है मैं हर आदेश खोल कार्यान्वित करने के लिए मुद्रित किया जा करना चाहते हैं कि stderr
। -x
विकल्प निर्दिष्ट करता है कि मैं चाहता हूँ एक ही करने के लिए मुद्रित stderr
- लेकिन मैं यह किया चाहते हैं के बाद आदेश का मूल्यांकन किया जाता है, लेकिन इससे पहले कि खोल यह चलाता है।
sh -cxv 'echo mv *'
आउटपुट
echo mv *
+ echo mv file1 file2 file3 file4 file5 folder
mv file1 file2 file3 file4 file5 folder
तो आप देखते हैं कि आदेश मैं फ़ीड खोल है echo mv *
और कमांड खोल कार्यान्वित के बाद *
का विस्तार किया गया है echo mv
उन फ़ाइलों और फ़ोल्डर के सभी के द्वारा पीछा किया।
डिफ़ॉल्ट रूप से शेल ग्लब्स का विस्तार करेगा जैसे:
sh -cxv 'echo file[1-5]'
आउटपुट
echo file[1-5]
+ echo file1 file2 file3 file4 file5
file1 file2 file3 file4 file5
यह set [+-]f
ग्लोब फंक्शन का परिणाम है :
sh -cxvf 'echo file[1-5]'
आउटपुट
echo file[1-5]
+ echo 'file[1-5]'
file[1-5]
इसलिए जब आप शेल में एक कमांड को डिफॉल्ट विकल्पों के साथ कॉन्फ़िगर करते हैं, जैसे mv *
शेल *
शब्द में फैलता है तो लोकल के अनुसार सॉर्ट की गई डायरेक्टरी में सभी फाइलों की एक तर्क सूची होती है। यह इस तर्क सूची के साथ (अनिवार्य रूप से) केexec(ve)
लिए syscall संलग्न है। तो सभी तर्क मिलते हैं क्योंकि शेल उन्हें ग्लोब करता है और उन्हें सॉर्ट करता है। इन प्रभावों को देखने के अलावा , आप डिबग को फिर से उपयोग कर सकते हैं जैसे:mv
mv
strace
sh -s -- mv * <<\SCRIPT
sed -n l /proc/$$/cmdline
echo "$@"
SCRIPT
आउटपुट
sh\000-s\000--\000mv\000file1\000file2\000file3\000file4\000file5\000folder\
\000$
mv file1 file2 file3 file4 file5 folder
और सुस्पष्ट रूप से:
( PS4= IFS=/; set -x mv *; : "/$*/" ) 2>&1
आउटपुट
: /mv/file1/file2/file3/file4/file5/folder/
मूल रूप से, शेल अपनी तर्क सूची के रूप mv
में निर्देशिका की सामग्री के साथ निष्पादित होता है (यदि यह खाली नहीं है और शुरुआत के नाम के साथ फाइल / फ़ोल्डर शामिल नहीं है .
) । mv
POSIX एक निर्देशिका के रूप में अपने अंतिम तर्क की व्याख्या करने के लिए निर्दिष्ट है यदि इसे दो से अधिक तर्कों के साथ लागू किया जाता है - उसी तरह से ln
है (क्योंकि वास्तव में, वे अंतर्निहित फ़ंक्शन में अविश्वसनीय रूप से समान उपकरण हैं) ।
echo
हालांकि पर्याप्त :
sh -cxv 'mv *' ; ls
आउटपुट
mv *
+ mv file1 file2 file3 file4 file5 folder
folder/
सभी फाइलें अंतिम तर्क में स्थानांतरित हो गईं - क्योंकि यह एक फ़ोल्डर है। अब अगर यह एक फ़ोल्डर नहीं है तो क्या होगा?
sh -cxv 'cd *; mv *'; ls . *
आउटपुट
cd *; mv *
+ cd folder
+ mv file1 file2 file3 file4 file5
mv: target ‘file5’ is not a directory
.:
folder/
folder:
file1 file2 file3 file4 file5
यह है कि कैसे POSIX निर्दिष्ट करता mv
है कि मामले में व्यवहार करना चाहिए:
mv [-if] source_file target_file
mv [-if] source_file... target_dir
पहले सिनोप्सिस रूप में, mv
उपयोगिता source_file ऑपरेंड द्वारा नामित फ़ाइल को लक्ष्य-फ़ाइल द्वारा निर्दिष्ट गंतव्य तक ले जाएगी । यह पहला सिनॉप्सिस फॉर्म माना जाता है जब अंतिम ऑपरेंड एक मौजूदा निर्देशिका का नाम नहीं देता है और एक मौजूदा निर्देशिका का संदर्भ देने वाला एक प्रतीकात्मक लिंक नहीं है। इस स्थिति में, यदि source_file एक गैर-निर्देशिका फ़ाइल का नाम देता है और target_file एक अनुगामी /slash
वर्ण के साथ समाप्त होता है , mv
तो इसे एक त्रुटि के रूप में माना जाएगा और कोई source_file ऑपरेंड संसाधित नहीं किया जाएगा।
दूसरे सिनॉप्सिस रूप में, mv
source_file operand द्वारा नामित प्रत्येक फ़ाइल को मौजूदा निर्देशिका में target_dir ऑपरेंड द्वारा नामित गंतव्य फ़ाइल में ले जाया जाएगा , या संदर्भित किया जाएगा यदि target_dir एक मौजूदा निर्देशिका का संदर्भ देने वाला एक प्रतीकात्मक लिंक है। प्रत्येक source_file के लिए गंतव्य पथ लक्ष्य निर्देशिका का संघटन होगा, /slash
यदि लक्ष्य a में समाप्त नहीं हुआ है /slash
, तो एक एकल वर्ण और source_file का अंतिम pathname घटक । यह दूसरा रूप तब माना जाता है जब अंतिम ऑपरेंड एक मौजूदा निर्देशिका का नाम देता है।
इसलिए यदि इसका *
विस्तार होता है: