'Bash -c' में तर्क जोड़ें


22

मान लीजिए कि मैं इस तरह से बैश के माध्यम से एक कमांड चलाना चाहता हूं:

/bin/bash -c "ls -l"

बैश मैन पेज के अनुसार, मैं इसे इस तरह भी चला सकता था:

#               don't process arguments after this one
#               |   pass all unprocessed arguments to command
#               |   |
#               V   V
/bin/bash -c ls -- -l

सिवाय इसके कि यह काम नहीं लगता (इसे नजरअंदाज किया गया)। क्या मैं कुछ गलत कर रहा हूं, या मैं मैन पेज गलत की व्याख्या कर रहा हूं?

आदमी से प्रासंगिक उद्धरण:

-C विकल्प मौजूद है, तो स्ट्रिंग से कमांड पढ़े जाते हैं। यदि स्ट्रिंग के बाद तर्क हैं, तो उन्हें $ 0 से शुरू करके, स्थितीय मापदंडों को सौंपा गया है।

तथा

ए - विकल्पों के अंत का संकेत देता है और आगे के विकल्प प्रसंस्करण को निष्क्रिय कर देता है। के बाद के किसी भी तर्क को फ़ाइल नाम और तर्क के रूप में माना जाता है।

जवाबों:


33

आप मैन पेज की गलत व्याख्या कर रहे हैं। सबसे पहले, --विकल्पों के अंत के बारे में संकेत देने के बारे में वह हिस्सा जो आप करने की कोशिश कर रहे हैं, के लिए अप्रासंगिक है। -cओवरराइड उस बिंदु से कमांड लाइन के बाकी, ताकि यह भविष्य में जा रहा नहीं है सब पर पार्टी के विकल्प से निपटने के माध्यम से, जिसका अर्थ है कि --आदेश के माध्यम से पारित किया जाएगा, विकल्प मार्कर की अंत के रूप में पार्टी द्वारा नियंत्रित नहीं।

दूसरी गलती यह है कि अतिरिक्त तर्कों को शेल प्रक्रिया के लिए स्थितीय मापदंडों के रूप में असाइन किया गया है, जो कमांड के लिए तर्कों के रूप में पारित नहीं किया गया है। इसलिए, आप जो करने की कोशिश कर रहे हैं, वह इनमें से एक के रूप में किया जा सकता है:

/bin/bash -c 'echo "$0" "$1"' foo bar
/bin/bash -c 'echo "$@"' bash foo bar

पहले मामले में, मापदंडों को प्रतिध्वनित करते हुए $0और $1स्पष्ट रूप से, और दूसरे मामले में, "$@"$ 0 को छोड़कर "सभी स्थितीय मापदंडों" के रूप में सामान्य रूप से विस्तार करने के लिए। ध्यान दें कि उस स्थिति में हमें कुछ उपयोग करने के लिए पास करना होगा $0; मैंने "बैश" चुना है क्योंकि यह $0सामान्य रूप से होगा, लेकिन कुछ और काम करेगा।

इस कारण से यह इस तरह से किया गया है, आप जो भी निर्देश देते हैं, उसे आप सीधे कमांड लिस्ट में पास करने के बजाय: ध्यान दें कि प्रलेखन कहता है कि "कमांड एस स्ट्रिंग से पढ़ी जाती है", बहुवचन। दूसरे शब्दों में, यह योजना आपको ऐसा करने की अनुमति देती है:

/bin/bash -c 'mkdir "$1"; cd "$1"; touch "$2"' bash dir file

लेकिन, ध्यान दें कि अपने मूल लक्ष्य को पूरा करने का एक बेहतर तरीका envइसके बजाय उपयोग करना हो सकता है bash:

/usr/bin/env -- "ls" "-l"

यदि आपको किसी ऐसी सुविधा की आवश्यकता नहीं है जो एक शेल प्रदान कर रही है, तो इसका उपयोग करने का कोई कारण नहीं है - envइस मामले में उपयोग करना तेज, सरल और कम टाइपिंग होगा। और आपको यह सुनिश्चित करने के लिए मुश्किल नहीं है कि यह सुरक्षित रूप से शेल मेटाचैकर या व्हॉट्सएप युक्त फ़ाइलनाम को संभालना होगा।


3

मुझे यकीन नहीं है कि आपका उद्देश्य क्या है, लेकिन अगर आप बस एक रुब गोल्डबर्ग मशीन बनाने की कोशिश कर रहे हैं - "एक गर्भनिरोधक, आविष्कार, उपकरण या उपकरण जो जानबूझकर अति-इंजीनियर या बहुत ही सरल कार्य करने के लिए ओवरडोन है जटिल फैशन ”- फिर प्रयास करें

sh -c 'ls $0' -l

या

sh -c 'ls $1' supercalifragilisticexpialidocious -l

या और भी

sh -c 'ls -$0' l

आपको यह समझने में सक्षम होना चाहिए कि ये ईश्वर के जवाब से कैसे काम करते हैं।

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