2011-09-17 17 views
21

के साथ एकाधिक तर्क युक्त परिवर्तक मैं अपने सभी तर्कों वाले एक बैश चर उत्पन्न करता हूं और उन तर्कों में रिक्त स्थान होते हैं। जब मैं उन तर्कों के साथ एक कमांड लॉन्च करता हूं - उदाहरण के लिए। ls $ args - उद्धरण सही ढंग से व्याख्या नहीं किए जाते हैं। यहां एक उदाहरण है - आवश्यक फाइलें बनाना और मिटा देना।बैश - वेरिएबल

#!/bin/bash 
f1="file n1" 
f2="file n2" 
# create files 
touch "$f1" "$f2" 
# concatenate arguments 
args="\"$f1\" \"$f2\"" 
# Print arguments, then launch 'ls' command 
echo "arguments :" $args 
ls $args 
# delete files 
rm "$f1" "$f2" 
इसी के साथ

, मैं के लिए कुछ "ऐसी कोई फाइल नहीं" त्रुटियाँ हैं "फ़ाइल, n1",

+0

http://stackoverflow.com/questions/2005192/how-to-execute-a-bash-command-stored-as-a-string-with -क्वॉट्स-एंड-एस्टेरिस्क –

उत्तर

38

आप समझते हैं एक array के लिए उपयोग कर सकते हैं " और n2 फ़ाइल" तर्क, इस तरह कुछ:

args=("$f1" "$f2") 
ls "${args[@]}" 

(जिस क्षण आप इस समय मार रहे हैं वह यह है कि एक बार टेरपोलेशन हुआ है इंट्रा- और इंटर-फाइलनाम रिक्त स्थान के बीच कोई अंतर नहीं है।)

+3

यह केवल बैश जैसे शैल के साथ काम करता है जो सरणी का समर्थन करता है। नीचे दिए गए 'eval' सभी यूनिक्स शैल के साथ काम करता है। –

+0

@ एरान-कुडबार्ड-बेल अच्छा, सच है, लेकिन सवाल कई बार 'बैश' का उल्लेख करता है, इसलिए यह समाधान सर्वोत्तम उत्तर की तरह दिखता है। – monnef

+1

मैं असहमत हूं, मेरे लिए वाक्यविन्यास अजीब और अपारदर्शी है। –

2

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

set -- "$f1" "$f2" 
touch "[email protected]" 
ls "[email protected]" 
rm "[email protected]" 
3

यह शायद सबसे खराब जवाब है, लेकिन आप IFS बदल सकते हैं। यह "आंतरिक क्षेत्र विभाजक" है और डिफ़ॉल्ट रूप से स्पेस + टैब + न्यूलाइन के बराबर है।

#!/bin/sh 
IFS=, 
MAR="-n,my file" 
cat $MAR 

स्क्रिप्ट ऊपर cat चलेंगे। पहला तर्क -n (क्रमांकित रेखाएं) होगा और दूसरा तर्क my file होगा।

26

eval का उपयोग करें, यह पहले किसी भी विस्तार का मूल्यांकन करेगा और उद्धरण देगा और फिर परिणामी स्ट्रिंग को निष्पादित करेगा जैसे कि इसे खोल में टाइप किया गया था।

args="'$f1' '$f2'" 
eval ls $args 

eval तो क्रियान्वित किया जाएगा ls 'file n1' 'file n2'

एक बहुत ही इसी तरह की समस्या थी, init स्क्रिप्ट में start_stop_daemon को /etc/default/ से प्राप्त चर में तर्क पारित करने के लिए कोशिश कर रहा।

+1

डाउनवॉटेड क्योंकि 'eval' में गंभीर सुरक्षा समस्याएं हैं - अधिक विस्तृत स्पष्टीकरण के लिए http://stackoverflow.com/a/37573041/120818 देखें, लेकिन मूल रूप से (http: //mywiki.wooledge से।संगठन/BashFAQ/048): "यह आपके कोड को एक बार के बजाय दो बार पार्स करने का कारण बनता है; इसका मतलब है कि, उदाहरण के लिए, यदि आपके कोड में परिवर्तनीय संदर्भ हैं, तो शैल का पार्सर उस चर की सामग्री का मूल्यांकन करेगा। यदि चर एक शेल कमांड होता है, खोल उस कमांड को चला सकता है, चाहे आप इसे चाहते हों या नहीं। " – HerbCSO

+3

यह कहने जैसा है कि आपको कभी भी प्रोग्रामिंग में गोटो का उपयोग नहीं करना चाहिए क्योंकि कुछ डेवलपर्स कोड को चूहे के घोंसले में बदलने के लिए उनका उपयोग करते हैं। ऐसे कई मामले हैं जहां eval सुरक्षा मुद्दों को पेश नहीं करेगा, मैं वास्तव में यह नहीं देखता कि यह एक वैध आलोचना है। –

+2

मैं @ ArranCudbard-Bell से सहमत हूं। आप पहले से ही परिवर्तनीय तर्क के साथ संभावित मनमानी कोड निष्पादित कर रहे हैं। 'Eval' का उपयोग करने से कोड को परिस्थितियों में पहले से ही कुछ भी करने की अनुमति नहीं मिलती है। – siride

0

यहां उद्धृत उद्धृत तर्कों के लिए मेरा नुस्खा है - ज्यादातर स्क्रिप्ट को पठनीय रखने के लिए उपयोग किया जाता है। लेकिन यह भी आसानी से कुछ तर्क बाहर टिप्पणी करने के लिए आरामदायक है:

PARAM1="a param with white spaces" 
PARAM2="some other funny param" 
PARAM3="third spaced param" 
#... 

PARAMS=$PARAM1 
PARAMS+='" "' 
PARAMS+=$PARAM2 
PARAMS+='" "' 
PARAMS+=$PARAM3 
#... 

eval command '"'$PARAMS'"' 
संबंधित मुद्दे