शेल स्क्रिप्ट: अंदर विकल्पों के साथ एक चर बनाना


11

मेरे पास निम्नलिखित मापदंडों के साथ एक rsync कमांड है:

rsync -avz --{partial,stats,delete,exclude=".*"}

मैं स्क्रिप्ट के बाद पुन: उपयोग करने के लिए उस पैरामीटर को एक चर के अंदर रखना चाहता हूं। कुछ इस तरह:

#!/bin/bash
VAR=rsync -avz --{partial,stats,delete,exclude=".*"}
$VAR /dir1 /dir2

मैंने बिना किसी सफलता के उद्धरण, एकल उद्धरण, कोष्ठक के साथ प्रयास किया है।


SO पर समान प्रश्न: stackoverflow.com/questions/13365553/…
बरमार

पहले इस मार्ग के नीचे होने के बाद: सुनिश्चित करें कि आपका अंतिम परिणामी कमांड स्ट्रिंग में कोई खाली तार नहीं है। यदि ऐसा होता है, तो rsync उन्हें मापदंडों के रूप में उपयोग कर सकता है और चूंकि वे अदृश्य हैं, इसलिए यह डीबग करना बहुत कठिन है। मेरे पास एक खाली पहला पैरामीटर था और rsync ने इसे कॉपी करने के लिए चीजों के स्रोतों में वर्तमान निर्देशिका के रूप में व्याख्या की।
जो

जवाबों:


12

एक चर में एक जटिल कमांड रखना एक अनुशंसित दृष्टिकोण नहीं है। BashFAQ / 050 देखें - मैं एक चर में एक कमांड डालने की कोशिश कर रहा हूं, लेकिन जटिल मामले हमेशा विफल होते हैं!

आपकी आवश्यकता वास्तव में सरल हो जाती है, यदि आप केवल एक चर के बजाय एक फ़ंक्शन का उपयोग करने का निर्णय लेते हैं और इसके लिए तर्क पास करते हैं।

कुछ इस तरह

rsync_custom() {
    [ "$#" -eq 0 ] && { printf 'no arguments supplied' >&2; exit 1 ; }
    rsync -avz --{partial,stats,delete,exclude=".*"} "$@"
}

और अब इसके लिए आवश्यक तर्क पास करें

rsync_custom /dir1 /dir2

फ़ंक्शन परिभाषा एक तरह से काफी सरल है, हम पहले चर का उपयोग करके इनपुट तर्क गिनती की जांच करते हैं $#जो शून्य नहीं होनी चाहिए। हम एक त्रुटि संदेश कहते हैं कि कोई तर्क नहीं दिया गया है। यदि मान्य तर्क हैं, तो "$@"फ़ंक्शन के लिए आपूर्ति की गई वास्तविक दलीलों का प्रतिनिधित्व करता है।

यदि यह एक ऐसा कार्य है, जिसका उपयोग आप अक्सर स्क्रिप्ट्स / कमांड-लाइन में भी करते हैं, तो इसे शेल स्टार्टअप-फाइल्स में जोड़ें .bashrc, .bash_profileउदाहरण के लिए।

या जैसा कि उल्लेख किया गया है, यह बेहतर पठनीयता के लिए अलग-अलग आर्गनों के लिए ब्रेस विस्तार का विस्तार करने के लिए सार्थक हो सकता है

rsync_custom() {
    [ "$#" -eq 0 ] && { printf 'no arguments supplied' >&2; exit 1 ; }
    rsync -avz --partial --stats --delete --exclude=".*" "$@"
}

5
VAR=rsync -avz --{partial,stats,delete,exclude=".*"}

यह -avzतर्क --partial, --statsआदि .. और वातावरण में VARसेट के साथ कमांड को चलाने की कोशिश करता rsyncहै।

VAR='rsync -avz --{partial,stats,delete,exclude=".*"}'

उद्धृत रूप काम नहीं करता है क्योंकि ब्रेसिज़ उद्धरणों में विस्तारित नहीं होते हैं, और न ही assigments के अंदर, और न ही वे एक चर के विस्तार के बाद विस्तारित नहीं होते हैं।

यदि आपको किसी चर में कमांड लाइन तर्क को संग्रहीत करने की आवश्यकता है, तो एक सरणी का उपयोग करें:

args=(rsync -avz --{partial,stats,delete,exclude=".*"})

अब "${args[@]}"करने के लिए विस्तार होगा rsync, -avz, --partialअलग शब्दों के रूप में, आदि।

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

args=(this that)
if something ; then
    args+=(another_arg)
fi
"$cmd" "${args[@]}"

1

आप कम से कम विकल्पों को आंशिक रूप से एक चर में सहेज सकते हैं:

opts=$(echo --{ignore-case,word-regexp,count,exclude='"sys*.*"'})

परीक्षण महत्वपूर्ण है, क्योंकि मास्किंग मुश्किल हो सकता है:

echo $opts
--ignore-case --word-regexp --count --exclude="sys*"

grep $opts bytes *.log 

चूंकि कई विकल्प हैं, जैसे इतिहास का उपयोग करना, उपनाम का उपयोग करना, फ़ंक्शन का उपयोग करना, कोई स्पष्ट उपयोग-मामला नहीं है जिसके बारे में मैं सोच सकता हूं। अलग-अलग कार्यक्रमों के बीच शायद ही कभी एक जटिल विकल्प साझा होता है, इसलिए इंटरैक्टिव शेल के लिए एक तदर्थ समाधान के लिए, अलियासिंग एक बेहतर तरीका लगता है:

alias cgrep='grep --ignore-case --word-regexp --count --exclude="sys*"'
cgrep bytes *.log

आपका नमूना

VAR=rsync -avz --{partial,stats,delete,exclude=".*"}

काम नहीं कर सकता, क्योंकि असाइनमेंट पहले खाली स्थान पर एंडेट है। आपको खाली नकाब उतारना होगा:

VAR='rsync -avz --{partial,stats,delete,exclude=".*"}'

परीक्षण के लिए एक बहुत ही खतरनाक बात, उस विकल्प के साथ, क्या यह नहीं है? चूंकि विकल्प में फिर से "," और एकल उद्धरण शामिल हो सकते हैं, मास्किंग बहुत जल्द मुश्किल हो सकती है। मैं एक उपनाम के लिए जाऊंगा या इतिहास पर भरोसा करूंगा।

एक उपनाम को कई सत्रों में निरंतर उपयोग के लिए ~ / .bashrc फ़ाइल में संग्रहीत किया जा सकता है। कार्यों को बाशेन में भी संग्रहीत किया जा सकता है, लेकिन आपको केवल उनकी आवश्यकता है, यदि आप मापदंडों को संभालना चाहते हैं, तो उसमें मूल्यांकन किए जाने के लिए फ़ंक्शन में पारित किया गया है।

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