की उपयोगिता क्या है: शेल स्क्रिप्टिंग में कमांड, यह देखते हुए कि यह स्पष्ट रूप से कुछ नहीं करता है?


27

शेल स्क्रिप्टिंग में टिप्पणियों के बारे में इस प्रश्न के उत्तर में , यह इंगित किया गया :है कि एक अशक्त कमांड है जो स्पष्ट रूप से कुछ भी नहीं करता है (लेकिन टिप्पणियों के लिए उपयोग नहीं किया जाना है)।

एक कमांड की उपयोगिता क्या होगी जो बिल्कुल कुछ भी नहीं करती है?



2
इस प्रश्न को भी देखें , जिसका यहाँ और भी बेहतर उत्तर है , अर्थात् :इसमें बिल्ट-इन होना आवश्यक है, जबकि trueऐसा नहीं है, जो चर के दायरे को प्रभावित करता है
Old Pro

2
यह स्पष्ट रूप से सुशोभित कुछ भी नहीं करता है ।
mikeserv

जवाबों:


19

मैं आमतौर पर trueछोरों में उपयोग करता हूं ; मुझे लगता है कि यह अधिक स्पष्ट है:

while true; do
    ...
done

एक जगह जो मैंने पाया है कि :वास्तव में बहुत आसान है, यदि आप कुछ से मेल खाना चाहते हैं, लेकिन वास्तव में कुछ भी नहीं करना चाहते हैं। उदाहरण के लिए:

case $answer in
    ([Yy]*) : ok ;;
    (*)     echo "stop."; exit 1 ;;
esac

3
मैं सहमत हूँ। trueएक शर्त के लिए, :एक एनओपी के लिए।
jw013

1
बैश स्वीकार करता है case a in a ) ;; esac। क्या कुछ गोले हैं जो इसे स्वीकार नहीं करते हैं?
काज

@ काज: पोसिक्स शेल व्याकरण के अनुसार , case ${var} in value);; *) do_something;; esacस्वीकार्य है। :आदेश खाली मामलों के लिए आवश्यक नहीं है।
रिचर्ड हैनसेन

12

मूल रूप से, यह निर्धारित करने के लिए इस्तेमाल किया गया था कि यह बॉर्न शेल कार्यक्रम था, सी संकलन कार्यक्रम के विपरीत। यह शेबंग और कई स्क्रिप्टिंग भाषाओं (csh, perl) से पहले था। आप अभी भी एक स्क्रिप्ट को शुरू कर सकते हैं ::

$ echo : > /tmp/xyzzy
$ chmod +x /tmp/xyzzy
$ ./xyzzy

यह आम तौर पर $SHELL(या /bin/sh) के खिलाफ स्क्रिप्ट चलाएगा ।

तब से, मुख्य उपयोग तर्कों का मूल्यांकन करना है। मैं अभी भी उपयोग करता हूं:

: ${EDITOR:=vim}

स्क्रिप्ट में एक डिफ़ॉल्ट मान सेट करने के लिए।


11

: लूप लिखने के लिए उपयोगी है जिसे भीतर से समाप्त किया जाना चाहिए।

while :
do
    ...stuff...
done

यह तब तक हमेशा के लिए चलेगा जब तक कि इसे कॉल न किया जाए breakया exitशेल को समाप्ति संकेत न मिले।


3
मुझे लगता है कि while true; do ...; doneपाठक के इरादों को बेहतर तरीके से while :; do ...; done
बताता है

9

जब आप शेल स्क्रिप्टिंग में "जब तक" बयान नहीं चाहते हैं, तो आप या तो "नहीं" स्थिति का उपयोग करते हैं, जो कुछ परीक्षणों के लिए नासमझ दिख सकता है, या आप सही खंड में ':' का उपयोग करते हैं, जिसमें वास्तविक कोड गलत है- खंड।

if [ some-exotic-condition ]
then
    :
else
    # Real code here
fi

यदि आप "नकारात्मक तर्क" का उपयोग नहीं करते हैं, तो "विदेशी स्थिति" कुछ ऐसा हो सकता है, जिसे आप नकारना नहीं चाहते हैं, या यह बहुत स्पष्ट है।


1
इससे उत्पन्न लिपियों में भी दिखाई देता है autoconfक्योंकि :खाली शाखाओं के लिए डिफ़ॉल्ट जोड़ना बहुत आसान है क्योंकि यह पता लगाना है कि स्थिति को कैसे उल्टा करना है।
डिट्रीच एप्प

2
मैं यह नहीं देख सकता कि नासमझ के !सामने चिपके रहना कितना [ some-exotic-condition ]नासमझ है, लेकिन नासमझ : elseहोने के बाद भी वह नहीं है।
काज

@ काज़ की बात अच्छी है। आइए ध्यान रखें कि विदेशी परिस्थितियों के साथ आना सबसे अच्छा है। अगर आपको यह सब नकारना है, तो यह एक बात है, लेकिन यह सिर्फ स्थिति को कम स्पष्ट कर सकता है। करता है एक '!' पूरी स्थिति को नकार दें, या सिर्फ पहला कार्यकाल? सर्वश्रेष्ठ कभी-कभी ':' सही खंड होता है।
ब्रूस एडगर

!टोकन एक पूरी कमान पाइप तत्व को नकारता। while ! grep ... ; do ... done या if ! [ ... ] ; then ... fi। यह मूल रूप से test/[]वाक्य रचना के लिए बाहरी है । : देखो pubs.opengroup.org/onlinepubs/9699919799/utilities/...
Kaz

5

मैंने केवल एक पंक्ति को अस्थायी रूप से टिप्पणी करने के लिए # वर्ण के अतिरिक्त इसका उपयोग किया है, ऐसी स्थिति में जिसमें पंक्ति को टिप्पणी करना वाक्यविन्यास त्रुटि पैदा करता है, शेल व्याकरण में एक दोष के कारण आदेशों के एक खाली अनुक्रम की अनुमति नहीं देता है :

if condition ; then
    :# temporarily commented out command
fi

इसके बिना: हमारे पास एक लापता कमांड अनुक्रम है, जो एक वाक्यविन्यास त्रुटि है।


4

दो मामले हैं जहाँ मुझे :उपयोगी लगता है:

डिफ़ॉल्ट चर असाइनमेंट

#!/bin/sh

# set VAR to "default value" if not already set in the environment
: "${VAR=default value}"

# print the value of the VAR variable.  Note that POSIX says the behavior
# of echo is implementation defined if the first argument is '-n' or if any
# argument contains a '\', so use printf instead of echo.
printf '%s\n' "VAR=${VAR}"

यह आपके शेल स्क्रिप्ट के उपयोगकर्ताओं को स्क्रिप्ट को संपादित किए बिना सेटिंग को ओवरराइड करने की अनुमति देने का एक सुविधाजनक तरीका है। (हालांकि, कमांड-लाइन तर्क बेहतर हैं क्योंकि आप अनपेक्षित व्यवहार का जोखिम नहीं उठाते हैं यदि उपयोगकर्ता संयोगवश आपके द्वारा अपने निर्यात किए गए वातावरण में चर का उपयोग करता है।) यहां बताया गया है कि उपयोगकर्ता सेटिंग को ओवरराइड कैसे करेगा:

VAR="other value" ./script

${VAR=value}वाक्य रचना सेट करने के लिए कहते हैं VARकरने के लिए valueकरता है, तो VARपहले से ही सेट नहीं है, तो चर के मूल्य का विस्तार। चूंकि हम अभी तक चर के मूल्य के बारे में परवाह नहीं करते हैं, इसलिए इसे :फेंकने के लिए नो-ऑप कमांड के तर्क के रूप में पारित किया जाता है।

:एक नो-ऑप कमांड होने के बावजूद , :कमांड को चलाने से पहले शेल द्वारा एक्सपेंशन किया जाता है ( कमांड नहीं !) :इसलिए वेरिएबल असाइनमेंट तब भी होता है (यदि लागू हो)।

इसके trueबजाय किसी अन्य कमांड का उपयोग करना या स्वीकार करना भी स्वीकार्य होगा :, लेकिन कोड पढ़ना कठिन हो जाता है क्योंकि इरादा कम स्पष्ट होता है।

निम्नलिखित स्क्रिप्ट भी काम करेगी:

#!/bin/sh

# print the value of the VAR variable.  Note that POSIX says the behavior
# of echo is implementation defined if the first argument is '-n' or if any
# argument contains a '\', so use printf instead of echo.
printf '%s\n' "VAR=${VAR=default value}"

लेकिन ऊपर बनाए रखने के लिए बहुत कठिन है। यदि ${VAR}उस printfलाइन के ऊपर एक लाइन का उपयोग किया जाता है , तो डिफ़ॉल्ट असाइनमेंट विस्तार को स्थानांतरित करना होगा। यदि डेवलपर उस असाइनमेंट को स्थानांतरित करना भूल जाता है, तो एक बग पेश किया जाता है।

खाली सशर्त ब्लॉक में कुछ डालना

खाली सशर्त ब्लॉकों को आमतौर पर टाला जाना चाहिए, लेकिन वे कभी-कभी उपयोगी होते हैं:

if some_condition; then
    # todo:  implement this block of code; for now do nothing.
    # the colon below is a no-op to prevent syntax errors
    :
fi

कुछ लोगों का तर्क है कि खाली सच्चे ifब्लॉक होने से टेस्ट को नकारने की तुलना में कोड को पढ़ना आसान हो सकता है। उदाहरण के लिए:

if [ -f foo ] && bar || baz; then
    :
else
    do_something_here
fi

यकीनन पढ़ने में आसान है:

if ! [ -f foo ] || ! bar && ! baz; then
    do_something_here
fi

हालाँकि मेरा मानना ​​है कि कुछ वैकल्पिक दृष्टिकोण हैं जो एक खाली सच्चे ब्लॉक से बेहतर हैं:

  1. एक समारोह में शर्त रखो:

    exotic_condition() { [ -f foo ] && bar || baz; }
    
    if ! exotic_condition; then
        do_something_here
    fi
    
  2. घुंघराले ब्रेसिज़ (या कोष्ठक के अंदर स्थिति रखें, लेकिन कोष्ठक एक उप-प्रक्रिया की प्रक्रिया शुरू करते हैं और उपधारा के अंदर पर्यावरण में किए गए कोई भी परिवर्तन उपधारा के बाहर दिखाई नहीं देंगे) को नकारने से पहले:

    if ! { [ -f foo ] && bar || baz; } then
        do_something_here
    fi
    
  3. ||इसके बजाय का उपयोग करें if:

    [ -f foo ] && bar || baz || {
        do_something_here
    }
    

    मैं इस दृष्टिकोण को पसंद करता हूं जब प्रतिक्रिया एक साधारण एक-लाइनर होती है, जैसे कि स्थिति को मुखर करना:

    log() { printf '%s\n' "$*"; }
    error() { log "ERROR: $*" >&2; }
    fatal() { error "$@"; exit 1; }
    
    [ -f foo ] && bar || baz || fatal "condition not met"
    

1

UNIX के प्राचीन संस्करणों में पुराने प्री-बॉर्न शेल में, :कमांड मूल रूप से लेबल के लिए निर्दिष्ट करने के लिए अभिप्रेत था goto(यह एक अलग कमांड थी जो इनपुट के लिए इनपुट को जीतता है, इसलिए लेबल एक अलग सिंटैक्स नहीं हो सकता है जो कि शेल के बारे में जानता है। ifयह एक अलग कमांड भी था।) यह जल्द ही टिप्पणियों के लिए उपयोग हो गया, इससे पहले कि एक टिप्पणी वाक्यविन्यास #था ( बैकस्पेस के लिए उपयोग किया गया था) और ये दिन संगतता के लिए जितना कुछ भी है।


0

एक बयान के रूप में इसका उपयोग करने के अलावा, जो कुछ भी नहीं करता है, आप इसका उपयोग एकल कथनों को टिप्पणी के लिए बाहर करने के लिए कर सकते हैं:


यह : echo write this line > myfileअभी भी एक टिप्पणी नहीं होगी क्योंकि अभी भी एक खाली फ़ाइल बनाई जाएगी।
Arcege

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