2009-01-09 21 views
20

सभी नए बनाए गए स्क्रिप्ट के लिए मानक के रूप में उपयोग करने के लिए एक अच्छा bash/ksh स्क्रिप्ट टेम्पलेट के लिए आपके सुझाव क्या होंगे?शैल स्क्रिप्ट टेम्पलेट

मैं आमतौर पर फ़ाइल नाम, सारांश, उपयोग, वापसी मूल्य, लेखक (ओं), चेंजलॉग के साथ एक टिप्पणी-आउट हेडर के साथ (#! लाइन के बाद) शुरू करता हूं और 80-चार लाइनों में फिट होगा।

सभी दस्तावेज लाइनें जो मैं डबल-हैश प्रतीकों से शुरू करता हूं: "##", इसलिए मैं उनके लिए आसानी से grep कर सकता हूं और स्थानीय var नाम "__" के साथ प्रीपेड किए जाते हैं।

कोई अन्य सर्वोत्तम प्रथाओं? युक्तियाँ? नामकरण की परंपरा? रिटर्न कोड के बारे में क्या?

धन्यवाद

संपादित करें: संस्करण नियंत्रण पर टिप्पणी: हम SVN सब ठीक है, लेकिन उद्यम में एक और विभाग एक अलग रेपो है और यह उनकी स्क्रिप्ट है - मैं कैसे पता है जो क्यू के साथ संपर्क करने के लिए अगर वहाँ है कोई @ लेखक की जानकारी नहीं? javadocs- इसी तरह की प्रविष्टियों में शेल संदर्भ में भी कुछ योग्यता है, आईएमएचओ, लेकिन मैं गलत हो सकता हूं। धन्यवाद प्रतिक्रियाओं

+4

लेखक (ओं)? बदलाव का? एक संस्करण नियंत्रण प्रणाली प्राप्त करें! – derobert

उत्तर

18

मैं 6 लाइनों के लिए नॉर्मन के जवाब का विस्तार चाहते हैं, और उन के अंतिम खाली है:

#!/bin/ksh 
# 
# @(#)$Id$ 
# 
# Purpose 

तीसरी लाइन है एक संस्करण नियंत्रण पहचान स्ट्रिंग - यह वास्तव में एक SCCS साथ एक संकर है मार्कर '@(#)' जिसे (एससीसीएस) प्रोग्राम what और एक आरसीएस संस्करण स्ट्रिंग द्वारा पहचाना जा सकता है जिसे आरसीएस के तहत फ़ाइल डालने पर विस्तारित किया जाता है, डिफ़ॉल्ट वीसीएस मैं अपने निजी उपयोग के लिए उपयोग करता हूं। आरसीएस प्रोग्राम ident$Id$ के विस्तारित रूप को चुनता है, जो $Id: mkscript.sh,v 2.3 2005/05/20 21:06:35 jleffler Exp $ जैसा दिख सकता है। पांचवीं पंक्ति मुझे याद दिलाती है कि लिपि में शीर्ष पर अपने उद्देश्य का वर्णन होना चाहिए; मैं शब्द को स्क्रिप्ट के वास्तविक विवरण के साथ प्रतिस्थापित करता हूं (यही कारण है कि इसके बाद कोई कॉलन नहीं है, उदाहरण के लिए)।

उसके बाद, शेल स्क्रिप्ट के लिए अनिवार्य रूप से कुछ भी मानक नहीं है। मानक टुकड़े दिखाई देते हैं, लेकिन प्रत्येक स्क्रिप्ट में कोई मानक खंड दिखाई नहीं देता है। (मेरी चर्चा मानती है कि बोर्ने, कॉर्न, या पॉसिक्स (बैश) खोल नोटेशन में लिपियों को लिखा गया है। #! सिगिल पाप में रहने वाले किसी भी व्यक्ति को सी शैल व्युत्पन्न क्यों डालने पर पूरी तरह से अलग चर्चा है।

tmp=${TMPDIR:-/tmp}/prog.$$ 
trap "rm -f $tmp.?; exit 1" 0 1 2 3 13 15 

...real work that creates temp files $tmp.1, $tmp.2, ... 

rm -f $tmp.? 
trap 0 
exit 0 

पहली पंक्ति, एक अस्थायी निर्देशिका चुनता है उपयोगकर्ता नहीं था/tmp को दोषी:)

उदाहरण के लिए, इस कोड को कुछ आकार अथवा प्रकार जब भी एक स्क्रिप्ट मध्यवर्ती (अस्थायी) फ़ाइलें बनाता है में प्रकट होता है एक विकल्प निर्दिष्ट करें ($ TMPDIR बहुत व्यापक रूप से पहचाना जाता है और इसे पीओएसआईक्स द्वारा मानकीकृत किया जाता है)। इसके बाद यह प्रक्रिया आईडी सहित फ़ाइल नाम उपसर्ग बनाता है। यह एक सुरक्षा उपाय नहीं है; यह एक साधारण समरूपता उपाय है, जो स्क्रिप्ट के कई उदाहरणों को एक-दूसरे के डेटा पर ट्रामलिंग से रोकता है। (सुरक्षा के लिए, गैर-सार्वजनिक निर्देशिका में गैर-अनुमानित फ़ाइल नामों का उपयोग करें।) दूसरी पंक्ति यह सुनिश्चित करती है कि 'rm' और 'exit' आदेश निष्पादित किए जाते हैं यदि शैल किसी भी सिग्नल SIGHUP (1), SIGINT (2) प्राप्त करता है), सिग्क्विट (3), सिगिप (13) या सिगरम (15)। 'rm' कमांड टेम्पलेट से मेल खाने वाली किसी भी मध्यवर्ती फ़ाइलों को हटा देता है; exit कमांड यह सुनिश्चित करता है कि स्थिति गैर-शून्य है, जो किसी प्रकार की त्रुटि का संकेत देती है। 'trap' का अर्थ है कि अगर किसी भी कारण से खोल निकलता है तो कोड भी निष्पादित किया जाता है - इसमें 'वास्तविक कार्य' चिह्नित अनुभाग में लापरवाही शामिल होती है। अंत में कोड किसी भी जीवित अस्थायी फ़ाइलों को हटा देता है, से बाहर निकलने पर जाल उठाना, और आखिरकार शून्य (सफलता) स्थिति से बाहर निकलता है। जाहिर है, अगर आप किसी अन्य स्थिति से बाहर निकलना चाहते हैं, तो आप यह सुनिश्चित कर सकते हैं कि rm और trap लाइनों को चलाने से पहले आप इसे एक चर में सेट करें, और फिर exit $exitval का उपयोग करें।

मैं आमतौर पर स्क्रिप्ट से पथ और प्रत्यय दूर करने के लिए निम्न का उपयोग कर, तो मैं $arg0 उपयोग कर सकते हैं जब त्रुटियों रिपोर्टिंग:

error() 
{ 
    echo "$arg0: $*" 1>&2 
    exit 1 
} 
:

arg0=$(basename $0 .sh) 

मैं अक्सर त्रुटियों की रिपोर्ट करने के लिए एक खोल फ़ंक्शन का उपयोग करें

यदि केवल एक या दो त्रुटि निकलती है, तो मैं फ़ंक्शन से परेशान नहीं हूं; यदि कोई और है, तो मैं करता हूं क्योंकि यह कोडिंग को सरल बनाता है। मैं कमांड का उपयोग करने के तरीके को सारांश देने के लिए usage नामक कम या कम विस्तृत कार्यों को भी बना देता हूं - फिर, केवल तभी, यदि एक से अधिक स्थान जहां इसका उपयोग किया जाएगा।

एक और काफी मानक टुकड़ा एक विकल्प पार्स पाश, उपयोग कर रहा है getopts खोल निर्मित:

vflag=0 
out= 
file= 
Dflag= 
while getopts hvVf:o:D: flag 
do 
    case "$flag" in 
    (h) help; exit 0;; 
    (V) echo "$arg0: version $Revision$ ($Date$)"; exit 0;; 
    (v) vflag=1;; 
    (f) file="$OPTARG";; 
    (o) out="$OPTARG";; 
    (D) Dflag="$Dflag $OPTARG";; 
    (*) usage;; 
    esac 
done 
shift $(expr $OPTIND - 1) 

या: बहस में चारों ओर "$ OPTARG" संभाल रिक्त स्थान

shift $(($OPTIND - 1)) 

उद्धरण। डीएफएलएजी संचयी है, लेकिन यहां इस्तेमाल किया गया नोटेशन तर्कों में रिक्त स्थान का ट्रैक खो देता है। उस समस्या के आसपास काम करने के लिए (गैर-मानक) तरीके भी हैं।

पहला शिफ्ट नोटेशन किसी भी खोल के साथ काम करता है (या अगर मैं '$(...)' के बजाय बैक-टिक का उपयोग करता हूं। आधुनिक गोले में दूसरे काम; यहां तक ​​कि ब्रांड्स के बजाय स्क्वायर ब्रैकेट के साथ एक विकल्प भी हो सकता है, लेकिन यह काम करता है इसलिए मुझे यह जानने के लिए परेशान नहीं किया गया है कि

अब के लिए एक अंतिम चाल यह है कि मेरे पास अक्सर जीएनयू और गैर-जीएनयू संस्करण दोनों प्रोग्राम होते हैं, और मैं चुनने में सक्षम होना चाहता हूं मैं उपयोग करता हूं।

: ${PERL:=perl} 
: ${SED:=sed} 

और तब, जब मैं पर्ल या sed आह्वान करने के लिए की जरूरत है, स्क्रिप्ट $PERL या $SED उपयोग करता है: मेरी स्क्रिप्ट में से कई, इसलिए, इस तरह के रूप चर का उपयोग करें। यह मेरी मदद करता है जब कुछ अलग-अलग व्यवहार करता है - मैं परिचालन संस्करण चुन सकता हूं - या स्क्रिप्ट को विकसित करते समय (मैं स्क्रिप्ट को संशोधित किए बिना कमांड में अतिरिक्त डीबग-केवल विकल्प जोड़ सकता हूं)।

+0

हाय @ जोनाथन नोटेशन क्या है ": $ {VAR: = file}"? अग्रिम धन्यवाद – tmow

+1

@tmow: नोटेशन '$ {VAR: = file} 'का अर्थ है कि यदि' $ VAR' एक गैर-खाली मान पर सेट है, तो उस मान का उपयोग करें, लेकिन यदि '$ VAR' सेट नहीं है या है खाली स्ट्रिंग पर सेट करें, फिर मान 'फ़ाइल' का उपयोग करें, और उस मान पर '$ VAR' सेट करें। तो, यह थोड़ा सा है (लेकिन इससे बहुत छोटा): '[-z "$ VAR"] && VAR = file; echo $ VAR'। –

+0

thx बहुत, यह वास्तव में उपयोगी है !!! – tmow

3

के लिए मैं

#!/bin/ksh 

सुझाव है और बस इतना ही। शैल स्क्रिप्ट के लिए हेवीवेट ब्लॉक टिप्पणियां? मुझे इच्छाएं मिलती हैं।

सुझाव:

  1. प्रलेखन डेटा या कोड, नहीं टिप्पणियां होना चाहिए। कम से कम usage() फ़ंक्शन। देखें कि कैसे ksh और अन्य एएसटी उपकरण प्रत्येक कमांड पर --man विकल्पों के साथ खुद को दस्तावेज करते हैं। (लिंक नहीं हो सकता क्योंकि वेब साइट डाउन है।)

  2. typeset के साथ स्थानीय चर घोषित करें। यही वह है। बुरा अंडरस्कोर की कोई ज़रूरत नहीं है।

7

किसी भी कोड है कि जंगली में जारी किया जाएगा निम्नलिखित लघु हैडर होना चाहिए जा रहा है:

# Script to turn lead into gold 
# Copyright (C) 2009 Joe Q Hacker - All Rights Reserved 
# Permission to copy and modify is granted under the foo license 
# Last revised 1/1/2009 

एक परिवर्तन लॉग कोड हेडर में जा रहा रखते हुए जब संस्करण नियंत्रण प्रणाली बहुत असुविधाजनक थे से एक विपर्ययण है। एक अंतिम संशोधित तिथि किसी को दिखाती है कि स्क्रिप्ट कितनी पुरानी है।

यदि आप bashisms पर भरोसा करने जा रहे हैं, तो #!/Bin/bash, not/bin/sh का उपयोग करें, क्योंकि sh किसी भी खोल का POSIX आमंत्रण है। भले ही/bin/sh इंगित करने के लिए इंगित करें, यदि आप इसे/bin/sh के माध्यम से चलाते हैं तो कई सुविधाएं बंद कर दी जाएंगी। अधिकांश लिनक्स वितरण स्क्रिप्ट नहीं लेते हैं जो बैशिस पर भरोसा करते हैं, पोर्टेबल होने का प्रयास करें।

# I am not crazy, this really is the only way to do this 

शैल पटकथा इतना आसान है कि (अपने एक प्रदर्शन लेखन जब तक कि कोई सिखाने के लिए कैसे यह करने के लिए) कोड है:

मेरे लिए

, शेल स्क्रिप्ट में टिप्पणी एक तरह से मूर्ख जब तक वे कुछ पढ़ रहे हैं लगभग हमेशा खुद को obviates।

कुछ गोले टाइप किए गए 'स्थानीय' चर खिलाए जाने को पसंद नहीं करते हैं। मेरा मानना ​​है कि इस दिन Busybox (एक आम बचाव खोल) उनमें से एक है। इसके बजाए GLOBALS_OBVIOUS बनाएं, इसे पढ़ने में बहुत आसान है, खासकर जब/bin/sh -x ./script.sh के माध्यम से डीबगिंग करते हैं।

मेरी व्यक्तिगत वरीयता है कि तर्क खुद के लिए बोलें और पार्सर के लिए काम को कम करें। उदाहरण के लिए, कई लोगों को लिख सकते हैं:

if [ $i = 1 ]; then 
    ... some code 
fi 

कहाँ मैं सिर्फ चाहते हैं:

[ $i = 1 ] && { 
    ... some code 
} 

इसी तरह, किसी को लिख सकते हैं:

if [ $i -ne 1 ]; then 
    ... some code 
fi 

... मैं जहां चाहते हैं:

[ $i = 1 ] || { 
    ... some code 
} 

एकमात्र बार जब मैं परंपरागत उपयोग करता हूं तो/th एन/और है अगर मिश्रण में फेंकने के लिए कोई और है।

बहुत अच्छे पोर्टेबल शेल कोड का एक बेहद पागल उदाहरण अध्ययन किया जा सकता है जो कि ऑटोकॉन्फ़ का उपयोग करने वाले अधिकांश मुफ्त सॉफ़्टवेयर पैकेजों में 'कॉन्फ़िगरेशन' स्क्रिप्ट को देखकर पढ़ा जा सकता है। मैं पागल कहता हूं क्योंकि इसकी 6300 लाइनें कोड जो हर सिस्टम को उस व्यक्ति को प्रदान करती है जिसमें यूनिक्स की तरह शेल है। आप उस तरह के ब्लोट को नहीं चाहते हैं, लेकिन यह कुछ पोर्टेबिलिटी हैक्स का अध्ययन करना दिलचस्प है .. जैसे कि उन लोगों के लिए अच्छा होना जो zsh को इंगित कर सकते हैं/bin/sh :)

एकमात्र अन्य सलाह मैं, यहां-डॉक्स में अपने विस्तार देखने होंगे यानी

cat <<EOF> foo.sh 
    printf "%s was here" "$name" 
EOF 

दे सकते हैं ... $ नाम का विस्तार करने के लिए, जब आप शायद ही स्थान पर चर छोड़ना चाहते हैं जा रहा है।इसके माध्यम से हल करें:

printf "%s was here" "\$name" 

जो इसे विस्तारित करने के बजाय एक चर के रूप में $ नाम छोड़ देगा।

मैं भी अत्यधिक अनुशंसा करता हूं कि सिग्नल पकड़ने के लिए जाल का उपयोग कैसे करें .. और उन हैंडलरों का उपयोग बॉयलरप्लेट कोड के रूप में करें। एक सरल SIGUSR1 के साथ धीमा करने के लिए चल रही स्क्रिप्ट को बताकर काफी आसान है :)

अधिकांश नए प्रोग्राम जो मैं लिखता हूं (जो टूल/कमांड लाइन उन्मुख हैं) शैल स्क्रिप्ट के रूप में शुरू होते हैं, यह यूनिक्स टूल्स प्रोटोटाइप करने का एक शानदार तरीका है।

आपको एसएचसी खोल स्क्रिप्ट कंपाइलर, check it out here भी पसंद हो सकता है।

+3

यदि आप यहां विस्तारित दस्तावेज़ों को विस्तारित नहीं करना चाहते हैं, तो विस्तार को दबाने के लिए << 'EOF' का उपयोग करें। जब आप कुछ चीजों का विस्तार करना चाहते हैं और कुछ चीजें विस्तारित नहीं होती हैं तो केवल बैकस्लाश का उपयोग करें। –

1

आम तौर पर, मेरे पास लिखने वाली प्रत्येक लिपि के लिए कुछ सम्मेलनों को रखना पसंद है। मैं सभी स्क्रिप्ट्स को धारणा के साथ लिखता हूं कि अन्य लोग उन्हें पढ़ सकते हैं।

मैं अपने शीर्ष लेख के साथ हर स्क्रिप्ट शुरू,

#!/bin/bash 
# [ID LINE] 
## 
## FILE: [Filename] 
## 
## DESCRIPTION: [Description] 
## 
## AUTHOR: [Author] 
## 
## DATE: [XX_XX_XXXX.XX_XX_XX] 
## 
## VERSION: [Version] 
## 
## USAGE: [Usage] 
## 

मुझे लगता है कि दिनांक स्वरूप का उपयोग करें, आसान ग्रेप/खोज के लिए। मैं '[' ब्रेसिज़ का उपयोग टेक्स्ट को इंगित करने के लिए करता हूं कि लोगों को खुद को दर्ज करने की आवश्यकता है। यदि वे किसी टिप्पणी के बाहर होते हैं, तो मैं उन्हें '# [' से शुरू करने का प्रयास करता हूं। इस तरह अगर कोई उन्हें चिपकाता है, तो यह इनपुट या टेस्ट कमांड के लिए गलत नहीं होगा। उदाहरण के रूप में इस शैली को देखने के लिए, मैन पेज पर उपयोग अनुभाग देखें।

जब मैं कोड की एक पंक्ति पर टिप्पणी करना चाहता हूं, तो मैं एक '#' का उपयोग करता हूं। जब मैं एक नोट के रूप में टिप्पणी कर रहा हूं, तो मैं एक डबल '##' का उपयोग करता हूं। /etc/nanorc उस सम्मेलन का भी उपयोग करता है। मुझे यह उपयोगी लगता है कि एक टिप्पणी को अलग करने के लिए जिसे निष्पादित नहीं किया गया था; छंद एक टिप्पणी है जो एक नोट के रूप में बनाई गई थी।

मेरे सभी खोल चर, मैं सीएपीएस में करना पसंद करता हूं। मैं 4 से 8 वर्णों के बीच रखने की कोशिश करता हूं, जब तक अन्यथा आवश्यक न हो। नाम उनके उपयोग के साथ यथासंभव सर्वोत्तम से संबंधित हैं।

मैं सफल होने पर भी 0 से बाहर निकलता हूं, या त्रुटियों के लिए 1। यदि स्क्रिप्ट में कई अलग-अलग प्रकार की त्रुटियां हैं (और वास्तव में किसी की मदद करेंगी, या किसी भी तरह से कुछ कोड में इस्तेमाल की जा सकती हैं), तो मैं 1 से अधिक दस्तावेज अनुक्रम का चयन करूंगा। सामान्य रूप से, निकास कोड कड़ाई से लागू नहीं होते हैं * निक्स दुनिया। दुर्भाग्य से मुझे कभी भी एक अच्छी सामान्य संख्या योजना नहीं मिली है।

मुझे मानक तरीके से तर्कों को संसाधित करना पसंद है। मैं हमेशा getopts पसंद करते हैं, getopt। मैं कभी भी 'पढ़ने' आदेशों और बयानों के साथ कुछ हैक नहीं करता हूं। मैं नेस्टेड आईएफएस से बचने के लिए केस स्टेटमेंट का भी उपयोग करना पसंद करता हूं। मैं लंबे विकल्पों के लिए एक अनुवाद स्क्रिप्ट का उपयोग करता हूं, इसलिए --help का अर्थ है- getopts के लिए। मैं या तो बैश (यदि स्वीकार्य है) या जेनेरिक sh में सभी स्क्रिप्ट लिखता हूं।

मैं कभी भी फ़ाइल नामों में बैश व्याख्या किए गए प्रतीकों (या किसी भी व्याख्याित प्रतीक) का उपयोग नहीं करता, या उस मामले के लिए कोई नाम नहीं। विशेष रूप से ... " '` $ & * #() {} [] -, मैं रिक्त स्थान के लिए _ का उपयोग

याद रखें, ये सिर्फ सम्मेलनों हैं मोटे के सर्वश्रेष्ठ अभ्यास,, लेकिन कभी कभी आप बाहर मजबूर हैं।। लाइनों। सबसे महत्वपूर्ण यह है कि आप अपनी परियोजनाओं के दौरान और भीतर रहें।

9

मैं उपयोग दस्तावेज के लिए ## लाइनों के पहले सेट का उपयोग करता हूं। अब मुझे याद नहीं है कि मैंने इसे पहले देखा था।

#!/bin/sh 
## Usage: myscript [options] ARG1 
## 
## Options: 
## -h, --help Display this message. 
## -n   Dry-run; only show what would be done. 
## 

usage() { 
    [ "$*" ] && echo "$0: $*" 
    sed -n '/^##/,/^$/s/^## \{0,1\}//p' "$0" 
    exit 2 
} 2>/dev/null 

main() { 
    while [ $# -gt 0 ]; do 
    case $1 in 
    (-n) DRY_RUN=1;; 
    (-h|--help) usage 2>&1;; 
    (--) shift; break;; 
    (-*) usage "$1: unknown option";; 
    (*) break;; 
    esac 
    done 
    : do stuff. 
} 
+3

स्क्रिप्ट grepping उपयोग() फ़ंक्शन पहले पर अच्छा लग रहा है लेकिन यह विफल रहता है अगर स्क्रिप्ट कहीं भी 'cd' निष्पादित करती है और' $ 0' एक पूर्ण फ़ाइल नाम नहीं है। मैं उपयोग संदेश() फ़ंक्शन वास्तव में गूंज/printf/cat उपयोग संदेश को चुनने के लिए चुनता हूं। – Jens

+0

आप स्क्रिप्ट के पूर्ण पथनाम को निर्धारित कर सकते हैं और एक चर में स्टोर कर सकते हैं। टिप्पणियों में शीर्ष पर उपयोग की जानकारी रखना अच्छा हो सकता है। यदि आप ऐसा करते हैं, तो टिप्पणियों से जानकारी प्रिंट करने के लिए स्क्रिप्ट को grepping कोड DRY बनाता है। – toxalot

2

आप क्या कर सकते हैं एक स्क्रिप्ट है कि एक स्क्रिप्ट & के लिए एक हैडर बनाता है और यह ऑटो अपने पसंदीदा संपादक में खुला है। मैंने देखा कि एक आदमी के लिए इस साइट पर है कि कार्य करें:

http://code.activestate.com/recipes/577862-bash-script-to-create-a-header-for-bash-scripts/?in=lang-bash

#!/bin/bash -  
#title   :mkscript.sh 
#description  :This script will make a header for a bash script. 
#author   :your_name_here 
#date   :20110831 
#version   :0.3  
#usage   :bash mkscript.sh 
#notes   :Vim and Emacs are needed to use this script. 
#bash_version :4.1.5(1)-release 
#=============================================================================== 
3

त्रुटि का पता लगाने को सक्षम करने से यह बहुत आसान जल्दी लिपि में समस्याओं का पता लगाने के लिए बनाता है: पहला त्रुटि पर

set -o errexit 

बाहर निकलें स्क्रिप्ट। इस तरह आप कुछ ऐसा करने के लिए जारी रखते हैं जो स्क्रिप्ट में पहले कुछ पर निर्भर था, शायद कुछ अजीब सिस्टम स्थिति के साथ समाप्त हो रहा है।

set -o nounset 

त्रुटियों के रूप में वैरिएबल को अनसेट करने के संदर्भों का संदर्भ लें। rm -you_know_what "$var/" जैसे अनसेट $var जैसी चीजों को चलाने से बचने के लिए बहुत महत्वपूर्ण है। यदि आप जानते हैं कि वेरिएबल अनसेट हो सकता है, और यह एक सुरक्षित स्थिति है, तो आप अलग-अलग मान का उपयोग करने के लिए ${var-value} का उपयोग कर सकते हैं यदि यह अनसेट या ${var:-value} अलग-अलग मान का उपयोग करने के लिए है, तो यह या खाली है।

set -o noclobber 

यह एक > जहां < सम्मिलित करने के लिए होती डालने की गलती है, और कुछ फ़ाइल जो आप पढ़ सकते हैं करने के लिए होती अधिलेखित करने के लिए आसान है। अगर आपको अपनी स्क्रिप्ट में एक फाइल को क्लॉबर करना है, तो आप इसे प्रासंगिक लाइन से पहले अक्षम कर सकते हैं और इसे बाद में सक्षम कर सकते हैं।

set -o pipefail 

आदेशों का पूरा सेट के निकास कोड के रूप में पाइप कमांड का एक सेट के पहले गैर-शून्य से बाहर निकलें कोड (अगर कोई है) का प्रयोग करें। यह पाइप किए गए आदेशों को डीबग करना आसान बनाता है।

shopt -s nullglob 

से बचें कि आपके /foo/* ग्लोब सचमुच व्याख्या की है अगर कोई है कि अभिव्यक्ति मिलान फ़ाइलें हैं।

आप दो लाइनों में इन सब को जोड़ सकते हैं:

set -o errexit -o nounset -o noclobber -o pipefail 
shopt -s nullglob 
4

मेरे बैश टेम्पलेट के रूप में नीचे है (में सेट मेरी vim configuration):

#!/bin/bash 

## DESCRIPTION: 

## AUTHOR: $USER_FULLNAME 

declare -r SCRIPT_NAME=$(basename "$BASH_SOURCE" .sh) 

## exit the shell(default status code: 1) after printing the message to stderr 
bail() { 
    echo -ne "$1" >&2 
    exit ${2-1} 
} 

## help message 
declare -r HELP_MSG="Usage: $SCRIPT_NAME [OPTION]... [ARG]... 
    -h display this help and exit 
" 

## print the usage and exit the shell(default status code: 2) 
usage() { 
    declare status=2 
    if [[ "$1" =~ ^[0-9]+$ ]]; then 
     status=$1 
     shift 
    fi 
    bail "${1}$HELP_MSG" $status 
} 

while getopts ":h" opt; do 
    case $opt in 
     h) 
      usage 0 
      ;; 
     \?) 
      usage "Invalid option: -$OPTARG \n" 
      ;; 
    esac 
done 

shift $(($OPTIND - 1)) 
[[ "$#" -lt 1 ]] && usage "Too few arguments\n" 

#==========MAIN CODE BELOW========== 
5

यह वह जगह है हैडर मैं अपने स्क्रिप्ट के लिए उपयोग खोल (बाश या क्ष)। यह man समान दिखता है और इसका उपयोग उपयोग() को भी प्रदर्शित करने के लिए किया जाता है।

#!/bin/ksh 
#================================================================ 
# HEADER 
#================================================================ 
#% SYNOPSIS 
#+ ${SCRIPT_NAME} [-hv] [-o[file]] args ... 
#% 
#% DESCRIPTION 
#% This is a script template 
#% to start any good shell script. 
#% 
#% OPTIONS 
#% -o [file], --output=[file] Set log file (default=/dev/null) 
#%         use DEFAULT keyword to autoname file 
#%         The default value is /dev/null. 
#% -t, --timelog     Add timestamp to log ("+%y/%m/%[email protected]%H:%M:%S") 
#% -x, --ignorelock    Ignore if lock file exists 
#% -h, --help     Print this help 
#% -v, --version     Print script information 
#% 
#% EXAMPLES 
#% ${SCRIPT_NAME} -o DEFAULT arg1 arg2 
#% 
#================================================================ 
#- IMPLEMENTATION 
#- version   ${SCRIPT_NAME} (www.uxora.com) 0.0.4 
#- author   Michel VONGVILAY 
#- copyright  Copyright (c) http://www.uxora.com 
#- license   GNU General Public License 
#- script_id  12345 
#- 
#================================================================ 
# HISTORY 
#  2015/03/01 : mvongvilay : Script creation 
#  2015/04/01 : mvongvilay : Add long options and improvements 
# 
#================================================================ 
# DEBUG OPTION 
# set -n # Uncomment to check your syntax, without execution. 
# set -x # Uncomment to debug this shell script 
# 
#================================================================ 
# END_OF_HEADER 
#================================================================ 

और यहाँ उपयोग कार्यों के साथ जाने के लिए है:

#== needed variables ==# 
SCRIPT_HEADSIZE=$(head -200 ${0} |grep -n "^# END_OF_HEADER" | cut -f1 -d:) 
SCRIPT_NAME="$(basename ${0})" 

    #== usage functions ==# 
usage() { printf "Usage: "; head -${SCRIPT_HEADSIZE:-99} ${0} | grep -e "^#+" | sed -e "s/^#+[ ]*//g" -e "s/\${SCRIPT_NAME}/${SCRIPT_NAME}/g" ; } 
usagefull() { head -${SCRIPT_HEADSIZE:-99} ${0} | grep -e "^#[%+-]" | sed -e "s/^#[%+-]//g" -e "s/\${SCRIPT_NAME}/${SCRIPT_NAME}/g" ; } 
scriptinfo() { head -${SCRIPT_HEADSIZE:-99} ${0} | grep -e "^#-" | sed -e "s/^#-//g" -e "s/\${SCRIPT_NAME}/${SCRIPT_NAME}/g"; } 

यहाँ है कि आप क्या प्राप्त करना चाहिए:

# Display help 
$ ./template.sh --help 

    SYNOPSIS 
    template.sh [-hv] [-o[file]] args ... 

    DESCRIPTION 
    This is a script template 
    to start any good shell script. 

    OPTIONS 
    -o [file], --output=[file] Set log file (default=/dev/null) 
    use DEFAULT keyword to autoname file 
    The default value is /dev/null. 
    -t, --timelog     Add timestamp to log ("+%y/%m/%[email protected]%H:%M:%S") 
    -x, --ignorelock    Ignore if lock file exists 
    -h, --help     Print this help 
    -v, --version     Print script information 

    EXAMPLES 
    template.sh -o DEFAULT arg1 arg2 

    IMPLEMENTATION 
    version   template.sh (www.uxora.com) 0.0.4 
    author   Michel VONGVILAY 
    copyright  Copyright (c) http://www.uxora.com 
    license   GNU General Public License 
    script_id  12345 

# Display version info 
$ ./template.sh -v 

    IMPLEMENTATION 
    version   template.sh (www.uxora.com) 0.0.4 
    author   Michel VONGVILAY 
    copyright  Copyright (c) http://www.uxora.com 
    license   GNU General Public License 
    script_id  12345 

आप यहाँ पूर्ण स्क्रिप्ट टेम्पलेट प्राप्त कर सकते हैं: http://www.uxora.com/unix/shell-script/18-shell-script-template

+0

आपकी पोस्ट में आपका पूरा टेम्प्लेट शामिल नहीं है और आपकी साइट कोड को "सामाजिक जैसी दीवार" के पीछे रखती है, इसे खराब व्यवहार माना जाना चाहिए। – Hultner

संबंधित मुद्दे