एक शेल स्क्रिप्ट में लिनक्स के साथ अस्थायी?


26

मैं क्या चाहता हूँ

1.) एक फ़ाइल को टेम्प्लेट के रूप में रखना, जिसमें चर $ $ $ मार्ग के लिए हैं (उदाहरण के लिए अपाचे कॉन्फिगरेशन)

2.) एक शेल स्क्रिप्ट होने से जो टेम्पलेट के चर में "भरता है" और डिस्क पर उत्पन्न फ़ाइल लिखता है।

क्या यह एक शेल स्क्रिप्ट के साथ संभव है। यदि आप कुछ आदेशों / उपकरणों का नाम दे सकते हैं तो मैं बहुत आभारी रहूंगा।

जवाबों:


23

यह बहुत संभव है। इसे लागू करने का एक बहुत ही सरल तरीका यह होगा कि यह टेम्प्लेट फ़ाइल के लिए वास्तव में स्क्रिप्ट हो और शेल वैरिएबल का उपयोग करें

#! /bin/bash
version="1.2.3"
path="/foo/bar/baz"
cat > /tmp/destfile <<-EOF
here is some config for version $version which should
also reference this path $path
EOF

आप इसे निर्दिष्ट करके कमांड लाइन पर भी कॉन्फ़िगर कर सकते हैं version=$1और path=$2इसलिए आप इसे पसंद कर सकते हैं bash script /foo/bar/baz 1.2.3। इससे -पहले कि ईओएफ लाइनों को नजरअंदाज करने से पहले व्हाट्सएप का कारण बने, <<EOFयदि आप उस व्यवहार को नहीं चाहते हैं तो सादे का उपयोग करें ।

ऐसा करने का एक और तरीका यह होगा कि आप खोज का उपयोग करें और sed की कार्यक्षमता को बदलें

#! /bin/bash
version="1.2.3"
path="/foo/bar/baz"
sed -e "s/VERSION/$version/g" -e "s/PATH/$path/" /path/to/templatefile > /tmp/destfile

जो स्ट्रिंग संस्करण और पथ के प्रत्येक उदाहरण को प्रतिस्थापित करेगा। यदि अन्य कारण हैं, तो वे तार टेम्पलेट फ़ाइल में होंगे जो आप अपनी खोज कर सकते हैं और VERSION या% VERSION% की जगह ले सकते हैं या गलती से ट्रिगर होने की संभावना कम हो सकती है।


18

के अलावा कोई आवश्यक उपकरण नहीं /bin/sh। फॉर्म की टेम्प्लेट फाइल दी

Version: ${version}
Path: ${path}

या मिश्रित शेल कोड के साथ भी शामिल है

Version: ${version}
Path: ${path}
Cost: ${cost}\$
$(i=1; for w in one two three four; do echo Param${i}: ${w}; i=$(expr $i + 1); done)

और एक खोल पार्स करने योग्य कॉन्फ़िगरेशन फ़ाइल की तरह

version="1.2.3-r42"
path="/some/place/under/the/rainbow/where/files/dance/in/happiness"
cost="42"

इसका विस्तार करना एक साधारण बात है

Version: 1.2.3-r42
Path: /some/place/under/the/rainbow/where/files/dance/in/happiness
Cost: 42$
Param1: one
Param2: two
Param3: three
Param4: four

वास्तव में, शेल चर में कॉन्फ़िगरेशन फ़ाइल के config_fileलिए पथ और टेम्पलेट फ़ाइल में पथ को देखते हुए template_file, आपको केवल इतना करना है:

. ${config_file}
template="$(cat ${template_file})"
eval "echo \"${template}\""

यह संभवत: टेम्पलेट फ़ाइल (@ mtinberg के समाधान) के रूप में पूर्ण शेल स्क्रिप्ट होने की तुलना में पूर्ववर्ती है।

पूरा अनुभवहीन टेम्पलेट विस्तारक कार्यक्रम:

#!/bin/sh

PROG=$(basename $0)

usage()
{
    echo "${PROG} <template-file> [ <config-file> ]"
}

expand()
{
    local template="$(cat $1)"
    eval "echo \"${template}\""
}

case $# in
    1) expand "$1";;
    2) . "$2"; expand "$1";;
    *) usage; exit 0;;
esac

यह मानक आउटपुट के विस्तार का उत्पादन करेगा; मानक आउटपुट को किसी फ़ाइल में पुनर्निर्देशित करें या वांछित आउटपुट फ़ाइल का उत्पादन करने के लिए स्पष्ट फैशन में उपरोक्त को संशोधित करें।

कैविट्स: यदि फ़ाइल में दोहरे उद्धरण चिह्नों ( ") का समावेश है तो टेम्प्लेट फ़ाइल विस्तार काम नहीं करेगा । सुरक्षा कारणों से, हमें संभवत: कुछ स्पष्ट संन्यास जांचों को शामिल करना चाहिए या इससे भी बेहतर, यदि शेल फ़ाइल बाहरी इकाई द्वारा बनाई गई है, तो शेल एस्केपिंग ट्रांसफॉर्मेशन करें।


1
इस तरह से मज़ेदार चीजें करने के लिए शेल स्क्रिप्ट का उपयोग करते हुए अभी भी सक्रिय रूप से लोगों को देखना बहुत अच्छा है। मेरे एक दोस्त ने शेल स्क्रिप्ट में एक घड़ी लिखी। github.com/tablespoon/fun/blob/master/cli-clock मजेदार समय वास्तव में।
चूजों

2
जब मुझे खुद ऐसा करते हुए यह उत्तर मिला, तो मैंने बहुत भोला दृष्टिकोण लागू किया और इसे
गीथूब

9

लिनक्स सीएलआई में इसका उपयोग करने का सबसे आसान तरीका envsubstपर्यावरण चर का उपयोग करना है ।

उदाहरण टेम्पलेट फ़ाइल apache.tmpl:

<VirtualHost *:${PORT}>
    ServerName ${SERVER_NAME}
    ServerAlias ${SERVER_ALIAS}
    DocumentRoot "${DOCUMENT_ROOT}"
</VirtualHost>

envsubstनई फ़ाइल के लिए रन और आउटपुट परिणाम my_apache_site.conf:

export PORT="443"
export SERVER_NAME="example.com"
export SERVER_ALIAS="www.example.com"
export DOCUMENT_ROOT="/var/www/html/"
envsubst < apache.tmpl > my_apache_site.conf

आउटपुट:

<VirtualHost *:443>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot "/var/www/html/"
</VirtualHost>

2
यह GNU गेटटेक्स्ट का हिस्सा है, और इसलिए सभी प्रमुख यूनिक्स प्लेटफार्मों (मैकओएस एक्स सहित) पर उपलब्ध है, साथ ही साथ माइक्रोसॉफ्ट विंडोज भी।
त्रिकसे

4

आपको शायद कठपुतली या बावर्ची जैसी विन्यास प्रबंधन प्रणाली पर ध्यान देना चाहिए । ये आसानी से कर सकते हैं जो आप ऊपर वर्णित हैं और बहुत कुछ।


1
धन्यवाद। बिल्कुल, मैं बावर्ची स्थापित है और चल रहा है। लेकिन यह बहुत अधिक उपरि जोड़ता है, जब आपको अपनी खुद की कुकबुक लिखनी होती है। मैं रूबी प्रोग्रामिंग भाषा नहीं जानता और मेरा निष्कर्ष था। आसान मामलों के लिए शेल स्क्रिप्ट के साथ ऐसा करना आसान है (यदि संभव हो तो)।
मार्कस

की तरह लग रहा कठपुतली और बावर्ची टेम्पलेट्स के लिए दोनों का उपयोग ERB, और कहा कि के हास्यास्पद आसान के साथ आरंभ करने के लिए। एक वेरिएबल को देखते हुए name, <%= name %>एक टेम्प्लेट में स्ट्रिंग को nameवैल्यू के साथ बदल दिया जाएगा । आप nameटेम्पलेट के बाहर कैसे परिभाषित करते हैं, दोनों प्रणालियों के बीच अंतर होता है, जाहिर है।
माइक रेनफ्रो

1
हाँ अस्थायी (बावर्ची के साथ) अपने आप में बिल्कुल आसान है। लेकिन शेफ को फ्रेमवर्क के रूप में उपयोग करना (और कुकबुक लिखना) बहुत समय की आवश्यकता होती है। डेटा को टेम्प्लेट में प्राप्त करने के लिए आपको यह समझने की आवश्यकता है कि कहां और कैसे शेफ डेटा स्रोत के "विलय" और बहुत सारे अन्य सामान का प्रबंधन करते हैं। मैंने अपनी खुद की रसोई की किताबें लिखना शुरू कर दिया है, लेकिन एक शेल स्क्रिप्ट मेरे विशेष मामले में 100 गुना तेज होगी ...
मार्कस

शेफ या कठपुतली के लिए बुनियादी ढाँचे को प्राप्त करना एक दर्द हो सकता है या आप यह पता लगाने की कोशिश कर सकते हैं कि उन्हें कैसे बिना सिर के चलाना है जो एक मजेदार साहसिक है। बॉक्स से बाहर खींचने या धकेलने के तरीके में एंसिबल ठीक काम करता है, इसलिए यह इसे बाहर निकालने और इसे स्वयं स्क्रिप्ट करने का बेहतर संतुलन बना सकता है। docs.ansible.com/template_module.html
चूजों

4

यदि आप शेल कोड के बजाय हल्के और वास्तविक टेम्पलेट चाहते हैं जो नई फाइलें उत्पन्न करता है, तो सामान्य विकल्प sed& awkया हैं perl। यहाँ एक लिंक है: http://savvyadmin.com/generate-text-from-templates-scripts-and-csv-data/

मुझे, मैं उस वर्ग में एक वास्तविक भाषा जैसे पर्ल, टेल, पाइथन, रूबी या कुछ और का उपयोग करूंगा। स्क्रिप्टिंग के लिए कुछ बनाया गया है। उन सभी के पास Google में अच्छे, सरल templating टूल और उदाहरण के टन हैं।


4

मैं उसके लिए shtpl का उपयोग करता हूं । (मेरा निजी प्रोजेक्ट, जिसका अर्थ है, यह व्यापक रूप से उपयोग में नहीं है। लेकिन शायद आप इसे वैसे भी परखना चाहते हैं)

उदाहरण के लिए, आप एक सीएसवी फ़ाइल से बाहर / / / नेटवर्क / इंटरफेस उत्पन्न करना चाहते हैं, आप इसे इस तरह कर सकते हैं:

CSV- फ़ाइल सामग्री (यहाँ test.csv):

eth0;10.1.0.10;255.255.0.0;10.1.0.1
eth1;192.168.0.10; 255.255.255.0;192.168.0.1

टेम्प्लेट (यहां इंटरफेस। पीपीएल):

#% IFS=';'
#% while read "Val1" "Val2" "Val3" "Val4"; do
auto $Val1 
iface $Val1 inet static
  address $Val2 
  netmask $Val3 
  gateway $Val4 

#% done < "$CSVFILE"

कमान:

$ CSVFILE=test.csv sh -c "$( shtpl interfaces.tpl )"

परिणाम:

auto eth0 
iface eth0 inet static
  address 10.1.0.10 
  netmask 255.255.0.0 
  gateway 10.1.0.1 

auto eth1 
iface eth1 inet static
  address 192.168.0.10 
  netmask  255.255.255.0 
  gateway 192.168.0.1

का आनंद लें!


1

मैंने FooF के उत्तर को बेहतर बनाया ताकि उपयोगकर्ता को दोहरे उद्धरण चिह्नों को मैन्युअल रूप से अनसैप करने की आवश्यकता न हो:

#!/bin/bash
template="$(cat $1)"
template=$(sed 's/\([^\\]\)"/\1\\"/g; s/^"/\\"/g' <<< "$template")
eval "echo \"${template}\""

1

मैंने हाल ही में एक bash script प्रकाशित की है, जो सिर्फ एक jinja-like टेम्पलेट सिंटैक्स का उपयोग करते हुए पूरा करती है। इसे कुकी कहा जाता है । यहाँ एक डेमो है:

कुकी डेमो


यह प्रश्न का उत्तर कैसे देता है?
राल्फफ्राइडल

1
@RalfFriedl मुझे यकीन नहीं है कि आपका क्या मतलब है। मैं सिर्फ यह सोचकर सवाल को टाल देता हूं कि मुझे कुछ याद आ गया होगा, लेकिन मैं इसे नहीं देख रहा हूं। वास्तव में, यह उस प्रश्न के किसी भी भाग का जवाब नहीं देता है जो पूछा गया था? यह लगभग ऐसा ही है जैसे मैंने इस प्रश्न का उत्तर देने के एकमात्र उद्देश्य से कुकी का निर्माण किया था ... जो मैंने किया। :)
ब्रायन बुगी

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

0

मुझे शायद इस पार्टी के लिए देर हो रही है। हालाँकि, मैं उसी समस्या को लेकर लड़खड़ा गया और मैंने कोड की कुछ पंक्तियों में अपना BASH टेम्पलेट इंजन बनाने का विकल्प चुना:

चलो कहते हैं कि आपके पास यह है file.template:

# My template
## Author
 - @NAME@ <@EMAIL@>

और यह rulesफाइल:

NAME=LEOPOLDO WINSTON
EMAIL=leothewinston\@leoserver.com

आप इस कमांड को निष्पादित करें:

templater rules < file.template

आप इसे प्राप्त करें:

# My template
## Author
 - LEOPOLDO WINSTON <leothewinston@leoserver.com>

आप इसे इसके द्वारा स्थापित कर सकते हैं:

 bpkg install vicentebolea/bash-templater

यह प्रोजेक्ट साइट है


0

@ FooF के शानदार उत्तर (नई टिप्पणियाँ टिप्पणी में प्रारूपित नहीं हुई) पर विस्तार करने के लिए, एक heredoc + नियंत्रण वर्णों का उपयोग करते हुए, आप मनमाने पात्रों और फ़ाइल नाम की अनुमति दे सकते हैं :

template() {
    # if [ "$#" -eq 0 ] ; then return; fi # or just error
    eval "cat <<$(printf '\x04\x04\x04');
$(cat $1)
"
}

यह किसी भी गैर-अशक्त चरित्र को स्वीकार करता है, और केवल तभी आरंभ होता है जब 3 ^Dबाइट्स अपनी ही रेखा पर दिखाई देते हैं (यथार्थवादी कभी नहीं)। zsh भी शून्य टर्मिनेटर का समर्थन करता है, इसलिए printf '\x00\x00\x00'काम करेगा। templateयहां तक ​​कि विश्वासघाती फ़ाइल नाम के लिए भी काम करता है:

for num in `seq 10`; do
    template 'foo "$ .html' # works
done

शेल शेल टेम्प्लेट, मनमानी कमांड, जैसे "विस्तार" कर सकते हैं $(launch_nukes.sh --target $(curl -sL https://freegeoip.app/csv/ | cut -d, -f 9,10))। महान शक्ति के साथ ...

संपादित करें: यदि आप वास्तव में नहीं चाहते हैं कि आपकी फाइलें आपको sudo -u nobody shपहले से ही (या किसी अन्य सुरक्षित उपयोगकर्ता) पर nukes लॉन्च करें।

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