मैं 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
उपयोग करता है: मेरी स्क्रिप्ट में से कई, इसलिए, इस तरह के रूप चर का उपयोग करें। यह मेरी मदद करता है जब कुछ अलग-अलग व्यवहार करता है - मैं परिचालन संस्करण चुन सकता हूं - या स्क्रिप्ट को विकसित करते समय (मैं स्क्रिप्ट को संशोधित किए बिना कमांड में अतिरिक्त डीबग-केवल विकल्प जोड़ सकता हूं)।
लेखक (ओं)? बदलाव का? एक संस्करण नियंत्रण प्रणाली प्राप्त करें! – derobert