इस बैश स्क्रिप्ट को कॉल करते समय फ़ाइलों के तर्क के लिए उद्धरण आवश्यक क्यों हैं?


13

मैं बैश स्क्रिप्टिंग के लिए काफी नया हूं। मेरे पास एक "टेस्टस्क्रिप्ट" है, जिसे मैंने अधिक उन्नत / उपयोगी स्क्रिप्ट के लिए आधार के रूप में उपयोग किया है:

#!/bin/bash
files=$1
for a in $files
do
    echo "$a"
done

जब मैं इसे किसी भी उद्धरण के बिना कहता हूं तो यह एक निर्देशिका में एक फ़ाइल उठाता है:

testscript *.txt

लेकिन जब मैं इसे उद्धरण के साथ कहता हूं तो यह सही ढंग से काम करता है और सभी पाठ फ़ाइलों को चुनता है:

testscript '*.txt'

यहाँ क्या हो रहा है?


बहुत स्पष्ट , बहुत स्पष्ट होने के लिए, इसे ठीक करने का सही तरीका आपकी स्क्रिप्ट में चलना for a in "$@"; do(या for a; do) है, इस प्रकार ग्लोब को बाहरी शेल पर छोड़ना है, उद्धरणों को छोड़ना नहीं है।
चार्ल्स डफी


यह कुआँ देखने लायक है। guide.bash.academy
vascowhite

जवाबों:


29

जब आप किसी कार्यक्रम को बुलाते हैं

testscript *.txt

तब आपका खोल विस्तार करता है और सभी मूल्यों को पूरा करता है। इसलिए, यह प्रभावी रूप से आपके प्रोग्राम को कॉल कर सकता है

testscript file1.txt file2.txt file3.txt file4.txt

अब आपका प्रोग्राम केवल देखता है $1और इसलिए केवल इस पर काम करता है file1.txt

कमांड लाइन पर उद्धृत करके आप *.txtस्क्रिप्ट के शाब्दिक स्ट्रिंग को पास कर रहे हैं , और वह वही है जो इसमें संग्रहीत है $1। आपका forलूप इसके बाद फैलता है।

आम तौर पर आप इस तरह की लिपियों में इस्तेमाल करते हैं "$@"और नहीं भी $1

यह सीएमडी स्क्रिप्टिंग से आने वाले लोगों के लिए एक "गोचा" है, जहां कमांड शेल ग्लोबिंग नहीं करता है (जैसा कि यह ज्ञात है) और हमेशा शाब्दिक स्ट्रिंग पास करता है।


6
बस, का उपयोग करते हुए (ऊपर जवाब के लेखक के अलावा अन्य लोगों के लिए) स्पष्ट करने के लिए "$@"(के रूप में करने का विरोध किया $@या $1 $2 $3) प्रत्येक फ़ाइल नाम उद्धृत हो जाएंगी "file1.txt" "file2.txt"आदि के लिए file1.txtयह व्यर्थ है, लेकिन अगर आपके पास my file.txt, के हवाले से है महत्वपूर्ण खोल को रोकने के लिए इसे दो फ़ाइलनामों में बदलने के लिए, एक का नाम myऔर एक का नाम file.txt। हमेशा उपयोगकर्ता इनपुट और ग्लोब एक्सपेंशन लेटेस्ट को उद्धृत करें कि आप किसी दिन बहुत नाखुश हैं।
सेठ रॉबर्टसन

2
और यह सिर्फ एक सैद्धांतिक नहीं है - मैक ओएस एक्स को एक बार एक अद्यतन स्क्रिप्ट के साथ भेज दिया गया था जिसने ठीक से तर्क नहीं दिया और कुछ परिस्थितियों में लोगों की हार्ड ड्राइव को हटा दिया।
शराबी

2
@fluffy, क्या आपके पास उसके बारे में एक लिंक है?
वाइल्डकार्ड

@Wildcard दुर्भाग्य से मैं इसके बारे में कोई लेख नहीं खोज पा रहा हूं, लेकिन टेक जगत में यह बड़ी खबर थी जब ऐसा हुआ। मैं यह कहना चाहता हूं कि यह 2003/2004 या उसके स्थान पर था, जब Apple अभी भी UNIX वितरक होने के लिए लटका हुआ था।
शराबी

1
@wildcard आह, यह पाया! xlr8yourmac.com/OSX/itunes2_erased_drives.html - यह वास्तव में एक iTunes अपग्रेड स्क्रिप्ट थी जो अपराधी थी।
शराबी

7

उद्धरण के बिना शेल *.txtस्क्रिप्ट को लागू करने से पहले फैलता है , इसलिए $1केवल पहली फ़ाइल है जो विस्तारित हो जाती है। सभी txtफाइलें उस बिंदु पर आपकी स्क्रिप्ट के लिए तर्क हैं (यह मानते हुए कि बहुत अधिक नहीं हैं)।

उद्धरण के साथ उस स्ट्रिंग को स्क्रिप्ट में विस्तारित किए बिना पारित किया जाता है, जो तब forविस्तार को करने देता है , जैसा कि आप उम्मीद कर रहे हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.