1 पॉइंट द्वारा GN⁺ 2 시간 전 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • Shell में : एक null command है, जो कोई कार्रवाई किए बिना सिर्फ arguments को evaluate करके छोड़ देता है; parameter expansion के साथ जोड़ने पर यह required arguments की जांच और default values सेट करना संक्षेप में कर सकता है
  • : "${1:?missing argument, aborting!}" में अगर $1 नहीं है या खाली है, तो diagnostic message stderr पर output होता है और shell non-zero status के साथ exit करता है
  • ${VAR:=default} को : के argument के रूप में देने पर expansion execute होता है लेकिन result string छोड़ दी जाती है, इसलिए expansion result को command के रूप में चलाए बिना सिर्फ default value सेट की जा सकती है
  • Redirection के जरिए file खाली करना और access availability जांचना, trap में खाली command, set -u environment में variable जांच, और खाली conditional branches में भी : का उपयोग किया जा सकता है
  • : "${VAR:=default}" variable name सिर्फ एक बार लिखता है, जिससे typo की संभावना घटती है, और while: में यह हमेशा सफल होने वाली condition बनकर infinite loop को व्यक्त करता है

Null command और parameter expansion

  • : एक built-in null command है, जो arguments को evaluate करने के बाद result को छोड़ देता है
    • इसका इतिहास 1971 के Thompson shell तक जाता है, और उस समय इसे label तथा Unix के पहले comment marker के रूप में भी इस्तेमाल किया जाता था
  • चार lines वाले conditional statement की जगह, required argument की जांच इस एक line से की जा सकती है
: "${1:?missing argument, aborting!}"
echo "Hello $1!"
  • Parameter expansion syntax ${name:?diagnostic} जांचता है कि $name set नहीं है या खाली है
    • अगर value नहीं है, तो diagnostic को stderr पर output करता है और shell को non-zero status के साथ exit करता है
    • अगर value है, तो $name जैसा result देता है
  • Null command के बिना सिर्फ ${HELLO:=123} execute करने पर expansion result 123 को command माना जाएगा और command not found होगा
    • : ${HELLO:=123} expansion को evaluate करके HELLO=123 सेट करता है और उसका result छोड़ देता है
  • : "${DATA_DIR:=/var/data}", DATA_DIR="${DATA_DIR:-/var/data}" से अलग, variable name केवल एक बार लिखता है, इसलिए DATA_DRI जैसी typo की संभावना कम हो जाती है

: का उपयोग करने के तरीके

  • Default value सेट करना

    • Expansion result को execute किए बिना छोड़ते हुए variable की default value सेट करता है
: "${DATA_DIR:=/var/data}"
: "${RETRIES:=3}"
  • File खाली करना और access जांचना

    • Redirection के साथ मिलाकर एक या अधिक files को खाली किया जा सकता है
: > error.log
: > error.log > access.log
  • Subshell और redirection का उपयोग करके file की read/write availability भी जांची जा सकती है
( : < dataset.json ) && echo YES
( : >> result.json ) && echo YES
  • जहां खाली command की जरूरत हो

    • trap की तरह, जब syntax के हिसाब से command जरूरी हो लेकिन असल में कोई काम नहीं करना हो, तब इसका इस्तेमाल किया जा सकता है
trap : INT
sleep 60
  • Conditional statement में खाली छोड़ी जाने वाली branch में भी रखा जा सकता है
if some-command; then
    :
else
    echo "command failed"
fi
  • कई variables की जांच

    • set -u enabled होने पर कई variables set हैं या नहीं, यह एक साथ जांचता है
set -u
: "$DEPLOY_ENV" "$HOST"
  • Infinite loop

    • : हमेशा successful condition है, इसलिए infinite loop को संक्षेप में लिखा जा सकता है
while :; do
  echo "I love colons"
  sleep 1
done

1 टिप्पणियां

 
GN⁺ 2 시간 전
Lobste.rs की टिप्पणियाँ
  • अगर prompt को इस तरह बनाया जाए, तो पूरी लाइन copy-paste करने पर भी prompt वाला हिस्सा ignore हो जाता है और केवल command execute होती है
    : hayalci@tassadar ~/src/dool ; jj rebase -s dxw -d mrn
    • Plan 9 से प्रेरणा लेकर shell का autocd option और यह format भी इस्तेमाल करते हैं
      ~/directoryname; <command>
      shell की command line copy करते समय हर बार command को उसी directory में cd कराया जाता है जहाँ वह मूल रूप से चलाया गया था
    • zsh में अदृश्य non-breaking space paste करने पर बाईं ओर की सामग्री मिटाने के लिए setup किया गया है
      nbsp=$'\u00A0'  
      PS1="...$nbsp"  
      bindkey -s $nbsp '^u'  
      
  • Makefile में output को अच्छा दिखाने के लिए colon का अक्सर उपयोग होता है
    out/%.o: src/%.c  
        @echo CC $@  
        @$(CC) -c -o $@ $<  
    
    इस तरीके में make कई echo processes को एक साथ चलाकर उसी stream में output लिख सकता है, जिससे वे एक-दूसरे में दखल दे सकते हैं। इसे ऐसे बदलने पर child process नहीं, बल्कि make process खुद output देता है
    out/%.o: src/%.c  
        : CC $@  
        @$(CC) -c -o $@ $<  
    
  • shell script में यह technique देखी थी, लेकिन man : या whatis : से उपयोगी documentation मिलना मुश्किल था
    यह true command जैसा है, लेकिन फर्क यह है कि यह --help, --version वगैरह पर खास response नहीं देता और characters भी कम हैं
    • Bash built-in commands को man के बजाय help से देखना चाहिए
      $ help :  
      :: :  
          Null command.
      
          No effect; the command does nothing.
      
          Exit Status:  
          Always succeeds.  
      
    • Fish में : सचमुच true का alias है
  • colon के बिना भी parameter expansion होता है, इसलिए सवाल है कि आखिर null command की जरूरत क्यों है
    • parameter expansion तो होता है, लेकिन null command की तरह result को consume करने वाला syntax न हो, तो shell expanded string को execute किए जाने वाले command के रूप में treat करता है। इसे FAQ में भी जोड़ा गया है
      % ${HELLO:=123}  
      zsh: command not found: 123  
      
      % : ${HELLO:=123}  
      % echo $HELLO  
      123  
      
    • interpolated string का result execute होने वाले command के रूप में interpret होता है
      #!/bin/sh  
      "${1:?missing argument, aborting!}"  
      
      $ sh foo.sh sh  
      sh-5.3$  
      
  • command type करते समय अगर उसे बाद में फिर चलाना हो, तो line की शुरुआत में colon लगाकर उसे history में save कर लेते हैं। बाद में history में वह line ढूँढकर सिर्फ पहला character हटाएँ, तो उसे सच में execute किया जा सकता है
    हालांकि arguments evaluate होने से पैदा होने वाले side effects में इसका उपयोग करने का विचार नहीं आया था
    • : के बजाय # लगाकर उसे comment के रूप में save भी किया जा सकता है। अगर बाद में चलाने वाली चीज है, तो फायदा यह है कि उसके अंदर के expressions पहले से evaluate नहीं होते
    • zsh में Meta-q या Alt-q से current line को थोड़ी देर के लिए हटाकर कोई दूसरा command चला सकते हैं, और खत्म होने पर original line command-line buffer में वापस आ जाती है
      https://nathangrigg.com/2014/04/zsh-push-line-or-edit/
  • macOS में अभी भी Bash 3 इस्तेमाल कर रहे हैं और यह error आता है
    -bash: !}": event not found
    • जानना चाहते हैं कि "!" का इस्तेमाल हटाने पर यह काम करता है या नहीं
  • Con-colon-sion का नीचे वाला code while true; do... की तुलना में लोगों को ज्यादा confuse कर सकता है
    while : colons are more than punctuation; do  
      echo "I love colons"  
      sleep 1  
    done  
    
    while true; do while :; do से सिर्फ तीन characters लंबा है, इसलिए काफी छोटा है, और यह code लेखक जो बात समझाना चाहता है उसके लिए सही example नहीं लगता
    • यह हूबहू follow करने वाला example नहीं, बल्कि wordplay के तौर पर डाला गया code है। अगर आप इस code को समझ सकते हैं, तो आप null command जानते हैं, और colon सचमुच punctuation से ज्यादा मायने रखता है
    • असल में शायद वे नीचे जैसा infinite loop दिखाना चाहते थे, लेकिन stylish तरीके से बताने की कोशिश में बात थोड़ी छूट गई
      while :; do  
          something  
      done