कैसे राख करने के लिए बैश-शैली सरणियों को पोर्ट करें?


13

कुछ समय पहले मैंने एक बैश स्क्रिप्ट लिखी है जो अब पर्यावरण के साथ चलना चाहिए ash

इस bashतरह था:

services=( "service1.service"
           "service2.service"                                       
           "service3.service" )  

for service in "${services[@]}"
do
   START $service                   
done

START()
{
   echo "Starting "$1
   systemctl start $1
}

वास्तव में सरणी में 40 सेवाएं हैं, और मैं इस संक्रमण को जितना संभव हो उतना दर्द रहित और साफ करना चाहता हूं। हमेशा bashआईएमएस का उपयोग करते रहे हैं । अब मैं स्क्रिप्ट को अधिक पोर्टेबल बनाने के लिए कार्य के साथ एक चुटकी में हूं।

पोर्टेबिलिटी के कारणों के लिए शायद शुद्ध ashसमाधान करना अच्छा होगा । लेकिन जब से मैं busyboxअपने निपटान में एक बहुत मजबूत है मैं कुछ पोर्टेबिलिटी बलिदान कर सकता है। केवल अगर पठनीयता में बहुत सुधार होता है, क्योंकि "क्लीन" स्क्रिप्ट एक मीट्रिक भी है।

इस मामले में पोर्टेबल और स्वच्छ समाधान क्या होगा ?

जवाबों:


8

इससे पहले कि सरणियों में bash, kshऔर अन्य गोले थे, सामान्य विधि एक सीमांकक चुनना था जो किसी भी तत्व में नहीं था (या जो किसी भी आवश्यक बचने के लिए कम से कम असामान्य था), और सभी तत्वों वाले स्ट्रिंग पर पुनरावृति करें, उस सीमांकक द्वारा अलग किया गया। व्हॉट्सएप आमतौर पर सबसे सुविधाजनक सीमांकक विकल्प है क्योंकि शेल पहले से ही डिफ़ॉल्ट रूप से व्हाट्सएप द्वारा "शब्दों" को विभाजित करता है (यदि आप चाहते हैं कि आप इसे कुछ अलग से विभाजित कर सकें तो IFS सेट कर सकते हैं)।

उदाहरण के लिए:

# backslash-escape any non-delimiter whitespace and all other characters that
# have special meaning to the shell, e.g. globs, parenthesis, ampersands, etc.
services='service1.service service2.service service3.service'

for s in $services ; do  # NOTE: do not double-quote $services here.
  START "$s"
done

$servicesयहां डबल-कोट्स नहीं होना चाहिए क्योंकि हम चाहते हैं कि शेल इसे "शब्दों" में विभाजित करे।


3

राख में ऐरे नहीं है। केवल एक चीज जो करीब आती है वह है पोजिशनल पैरामीटर, इसलिए आप कर सकते हैं

set -- "service1.service" \
       "service2.service" \
       "service3.service"

for service in "$@"
do
   START $service
done

3

यदि आपको केवल एक बार सेवाओं की सूची को संदर्भित करने की आवश्यकता है, तो आप यहाँ-डॉक्टर का उपयोग कर सकते हैं:

while IFS= read -r service
do
   START "$service"
done << END
service1.service
service2.service
service3.service
END

ध्यान दें कि सेवा नामों को सूची में उद्धृत नहीं किया जाना चाहिए (हालांकि "$service"संभवतः उद्धृत किया जाना चाहिए, जब तक कि आपके पास एक अच्छा कारण न हो)। यदि आप सेवा नामों को इंडेंट करना चाहते हैं, तो <<-इसके बजाय का उपयोग करें <<और टैब के साथ नामों को इंडेंट करें:

while IFS= read -r service
do
   START "$service"
done <<- END
        service1.service
        service2.service
        service3.service
END
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.