गतिशील रूप से एक कमांड बनाएँ


9

मैं एक स्क्रिप्ट पर काम कर रहा हूं और मुझे tarकमांड को गतिशील रूप से बनाने की आवश्यकता है ।

यहाँ दो उदाहरण बताए गए हैं कि मैं क्या करने की कोशिश कर रहा हूँ:

#!/bin/bash

TAR_ME="/tmp"

EXCLUDE=("/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*")
_tar="tar "`printf -- '--exclude="%s" ' "${EXCLUDE[@]}"`" -zcf tmp.tar.gz"
echo COMMAND: "${_tar}"
${_tar} "$TAR_ME"

echo -e "\n\nNEXT:\n\n"

EXCLUDE=("--exclude=/tmp/hello\ hello" "--exclude=/tmp/systemd*" "--exclude=/tmp/Temp*")
_tar="tar "`printf -- '%s ' "${EXCLUDE[@]}"`" -zcf test.tar.gz"
echo COMMAND: "${_tar}"
${_tar} "$TAR_ME"

मैं _tarएक कमांड के रूप में उपयोग करने में सक्षम होना चाहता हूं , मैं इसे क्लासिक पथ के साथ काम करने में सक्षम हूं, लेकिन मुझे फ़ोल्डर्स के नाम के रिक्त स्थान के साथ काम करने की आवश्यकता है। और हर बार मुझे ऐसी त्रुटियां मिलीं जो दिखती हैं:

COMMAND: tar --exclude="/tmp/hello hello" --exclude="/tmp/systemd*" --exclude="/tmp/Temp*"  -zcf tmp.tar.gz /tmp
tar: hello": Cannot stat: No such file or directory

COMMAND: tar --exclude=/tmp/hello\ hello --exclude=/tmp/systemd* --exclude=/tmp/Temp*  -zcf test.tar.gz 
tar: hello: Cannot stat: No such file or directory

बस आपको एक चीज जानने की जरूरत है, मुझे बहुत पुरानी मशीनों पर काम करने के लिए मेरी स्क्रिप्ट की आवश्यकता है, जिसका अर्थ है कि मैं अंतिम बैश सुविधाओं का उपयोग नहीं कर सकता।


मेरा मानना ​​है कि --exclude विकल्प इसके बाद केवल एक स्ट्रिंग को स्वीकार कर सकता है। हालांकि आपके पास कई --exclude स्टेटमेंट हो सकते हैं। शायद कोशिश करें "--exclude = / tmp / hello --exclude = hello" उफ़। कोई बात नहीं। मैंने गलत समझा।
लुईस एम

@ LewisM मुझे लगता है कि ओपी निर्देशिका को बाहर करना चाहता है "/ tmp / हैलो हैलो" (हाँ, एक स्थान के साथ।
आर्केमोर

@ShellCode के बारे में सभी को बाहर करने के बारे में क्या है, उदाहरण के लिए "--exclude = / tmp / हैलो हैलो"
आर्केम

हाँ। इसलिए मैंने ऊप्स स्टेटमेंट बाद में रखा। :)
लुईस एम

evalनिष्पादन के सामने कैसे रखा जाए ?
जिमीज

जवाबों:


11

एक निष्पादन योग्य स्ट्रिंग बनाने का प्रयास न करें। इसके बजाय एक सरणी में तर्कों का निर्माण करें और कॉल करते समय उपयोग करें tar(आप पहले से ही किसी सरणी का उपयोग ठीक से कर रहे हैं EXCLUDE):

#!/bin/bash

directory=/tmp

exclude=( "hello hello" "systemd*" "Temp*" )

# Now build the list of "--exclude" options from the exclude array:
for elem in "${exclude[@]}"; do
    exclude_opts+=( --exclude="$directory/$elem" )
done

# Run tar
tar -cz -f tmp.tar.gz "${exclude_opts[@]}" "$directory"

के साथ /bin/sh:

#!/bin/sh

directory=/tmp

set -- "hello hello" "systemd*" "Temp*"

# Now build the list of "--exclude" options from the $@ array
# (overwriting the values in $@ while doing so)
for elem do
    set -- "$@" --exclude="$directory/$elem"
    shift
done

# Run tar
tar -cz -f tmp.tar.gz "$@" "$directory"

नोट के हवाले से $@में shकोड और दोनों की ${exclude[@]}और ${exclude_opts[@]}में bashकोड। यह सुनिश्चित करता है कि सूचियों को व्यक्तिगत रूप से उद्धृत तत्वों तक विस्तारित किया गया है।

सम्बंधित:


2
mix(){
        p=$1; shift; q=$1; shift; c=
        i=1; for a; do c="$c $q \"\${$i}\""; i=$((i+1)); done
        eval "${p%\%*}$c${p#*\%}"
}
mix 'tar % -zcf tmp.tar.gz' --exclude "/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*"

EXCLUDE=("/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*")
mix 'tar % -zcf tmp.tar.gz' --exclude "${EXCLUDE[@]}"

यहां उत्तर का विस्तार । यह किसी भी bashisms पर भरोसा नहीं करता है, यह डेबियन के /bin/shसाथ, और साथ ठीक काम करेगा busybox


आपकी मदद के लिए बहुत बहुत धन्यवाद, लेकिन मैं वास्तव में eval पसंद नहीं करता, यह काफी खतरनाक है ... इसके अलावा, इस कोड को समझना काफी कठिन है, क्या आपके पास कुछ आसान नहीं है? : / स्क्रिप्ट वितरित की जाएगी, इसलिए मुझे इसे यथासंभव सरल रखना होगा ...
ShellCode

यह खतरनाक नहीं है। इसके साथ चलाओ set -x। वास्तव में आप क्या नहीं समझते हैं?
मॉसवी

इसके अलावा, stackoverflow पर मूल उत्तर पढ़ें। इसमें एक डेमो शामिल है।
मॉसवी

हालांकि यह काफी अच्छी तरह से काम करता है ... प्रतीक्षा करने के लिए कि क्या किसी के पास क्लीनर का जवाब है, अन्यथा मैं आपकी बात मानूंगा। हो सकता है कि उस कोड में कुछ भी गलत न हो, लेकिन हर बार जब मुझे एक इवैल दिखाई देता है, तो मुझे डर लगता है कि कोड कमांड इंजेक्शन का कारण बन सकता है, इसीलिए मैं इससे बचने की कोशिश करता हूं
ShellCode

मैंने उत्तर को अनुक्रमित के लिए एक फिक्स के साथ अद्यतन किया है> 9. आप यह देखने के लिए कि क्या वास्तव में मिल रहा है (eval फ़ाइल नाम नहीं देखता है) के साथ eval को बदल सकते हैं
मोवी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.