मैं शेल स्क्रिप्ट में सहायता विधि कैसे जोड़ सकता हूं?


128

यदि कोई -hविशेषता शेल स्क्रिप्ट में दी गई है, तो मैं कैसे जांचूं? उपयोगकर्ता द्वारा कॉल करने पर मैं एक सहायता संदेश प्रदर्शित करना चाहूंगा myscript.sh -h


जवाबों:


173

यहाँ bash के लिए एक उदाहरण है:

usage="$(basename "$0") [-h] [-s n] -- program to calculate the answer to life, the universe and everything

where:
    -h  show this help text
    -s  set the seed value (default: 42)"

seed=42
while getopts ':hs:' option; do
  case "$option" in
    h) echo "$usage"
       exit
       ;;
    s) seed=$OPTARG
       ;;
    :) printf "missing argument for -%s\n" "$OPTARG" >&2
       echo "$usage" >&2
       exit 1
       ;;
   \?) printf "illegal option: -%s\n" "$OPTARG" >&2
       echo "$usage" >&2
       exit 1
       ;;
  esac
done
shift $((OPTIND - 1))

किसी फ़ंक्शन के अंदर इसका उपयोग करने के लिए:

  • के "$FUNCNAME"बजाय का उपयोग करें$(basename "$0")
  • local OPTIND OPTARGकॉल करने से पहले जोड़ेंgetopts

1
मैं एक फ़ंक्शन के अंदर यह कोशिश कर रहा हूं, लेकिन जब मैं फ़ंक्शन को चलाने की कोशिश करता हूं तो मुझे यह त्रुटि मिलती है "आधार: अमान्य विकल्प - 'b'"। ऐसा लगता है कि यह basenameअग्रणी डैश के साथ "-बैश" को पारित करने की कोशिश कर रहा है ।
मॉर्गन एस्टे

5
एक समारोह का उपयोग "$FUNCNAME"नहीं उल्टा "$0"। इसके अलावा, जोड़नेlocal OPTIND OPTARG
ग्लेन जैकमैन

धन्यवाद। FUNCNAMEकाम करता है। मेरे पास एक फ़ाइल के अंदर मेरे सभी कार्य हैं, इसलिए यह उन्हें दूसरों के लिए कुछ उपयोगी बनाने के लिए एकदम सही है।
मॉर्गन एस्टे

5
@ सिगुर, सुनिश्चित करें कि आप "$usage" हर जगह का उपयोग करने के लिए बोली लगाते हैं ।
ग्लेन जैकमैन

1
किसलिए है shift $((OPTIND - 1))?
हिप्पनिया

45

शेल स्क्रिप्ट के लिए पहला तर्क चर के रूप में उपलब्ध है $1, इसलिए सबसे सरल कार्यान्वयन होगा

if [ "$1" == "-h" ]; then
  echo "Usage: `basename $0` [somestuff]"
  exit 0
fi

लेकिन शुभ ने क्या कहा।


धन्यवाद @MarkBooth, टाइपो सही (उद्धरणों में लपेटकर सुधार)
seb

आपको किसी वैरिएबल, स्रोत: github.com/bahamas10/bash-style-guide#bashism
JREV

2
हां, हालांकि ओपी ने बैश को निर्दिष्ट नहीं किया है, और [पोसिक्स-अनुरूप संस्करण है।
seb

नोट - अंदर का उपयोग कर के लिए function: आप बदलना चाहिए exit 0साथ returnअगर आप अपने समारोह चलाने के बाद अपने खोल समाप्त करने के लिए नहीं करना चाहती। (मैंने इसे 😂 से पहले किया है)
इल्लुमिनेटर

29

यहाँ एक हिस्सा है जिसका उपयोग मैं VNC सर्वर शुरू करने के लिए करता हूँ

#!/bin/bash
start() {
echo "Starting vnc server with $resolution on Display $display"
#your execute command here mine is below
#vncserver :$display -geometry $resolution
}

stop() {
echo "Killing vncserver on display $display"
#vncserver -kill :$display
}

#########################
# The command line help #
#########################
display_help() {
    echo "Usage: $0 [option...] {start|stop|restart}" >&2
    echo
    echo "   -r, --resolution           run with the given resolution WxH"
    echo "   -d, --display              Set on which display to host on "
    echo
    # echo some stuff here for the -a or --add-options 
    exit 1
}

################################
# Check if parameters options  #
# are given on the commandline #
################################
while :
do
    case "$1" in
      -r | --resolution)
          if [ $# -ne 0 ]; then
            resolution="$2"   # You may want to check validity of $2
          fi
          shift 2
          ;;
      -h | --help)
          display_help  # Call your function
          exit 0
          ;;
      -d | --display)
          display="$2"
           shift 2
           ;;

      -a | --add-options)
          # do something here call function
          # and write it in your help function display_help()
           shift 2
           ;;

      --) # End of all options
          shift
          break
          ;;
      -*)
          echo "Error: Unknown option: $1" >&2
          ## or call function display_help
          exit 1 
          ;;
      *)  # No more options
          break
          ;;
    esac
done

###################### 
# Check if parameter #
# is set too execute #
######################
case "$1" in
  start)
    start # calling function start()
    ;;
  stop)
    stop # calling function stop()
    ;;
  restart)
    stop  # calling function stop()
    start # calling function start()
    ;;
  *)
#    echo "Usage: $0 {start|stop|restart}" >&2
     display_help

     exit 1
     ;;
esac

यह थोड़ा अजीब है कि मैंने एक अलग मामले में स्टार्ट स्टॉप रिस्टार्ट रखा, लेकिन यह काम करना चाहिए


यदि आप -d को एक खाली विकल्प देते हैं; यह अनंत लूप नहीं होगा?
ज़ेरोबाने

आप हेल्पर फ़ंक्शन में 1 से बाहर क्यों आते हैं?
jeantimex

17

एक त्वरित एकल विकल्प समाधान के लिए, का उपयोग करें if

यदि आपके पास जाँच करने के लिए केवल एक ही विकल्प है और यह हमेशा पहला विकल्प ( $1) होगा तो सबसे सरल समाधान ifएक परीक्षण ( [) के साथ है। उदाहरण के लिए:

if [ "$1" == "-h" ] ; then
    echo "Usage: `basename $0` [-h]"
    exit 0
fi

ध्यान दें कि पॉज़िक्स संगतता के लिए =भी काम करेगा ==

बोली क्यों $1?

$1उद्धरणों में संलग्न होने का कारण यह है कि यदि कोई नहीं है, $1तो शेल चलाने की कोशिश करेगा if [ == "-h" ]और विफल हो जाएगा क्योंकि ==केवल एक ही तर्क दिया गया है जब यह दो की उम्मीद कर रहा था:

$ [ == "-h" ]
bash: [: ==: unary operator expected

कुछ और अधिक जटिल उपयोग के लिए getoptयाgetopts

जैसा कि दूसरों ने सुझाव दिया है , यदि आपके पास एक से अधिक सरल विकल्प हैं, या किसी तर्क को स्वीकार करने के लिए आपके विकल्प की आवश्यकता है, तो आपको निश्चित रूप से उपयोग करने की अतिरिक्त जटिलता के लिए जाना चाहिए ।getopts

एक त्वरित संदर्भ के रूप में, मुझे 60 सेकंड का गेटटॉप ट्यूटोरियल पसंद है

आप getoptअंतर्निहित शेल के बजाय कार्यक्रम पर विचार करना चाह सकते हैं getopts। यह लंबे समय से विकल्प के उपयोग की अनुमति देता है, और विकल्प के बाद गैर विकल्प तर्क (जैसे foo a b c --verboseबल्कि सिर्फ तुलना में foo -v a b c)। यह Stackoverflow जवाब बताता है कि GNU का उपयोग कैसे किया जाता है getopt

jeffbyrnes उल्लेख किया है कि मूल लिंक की मृत्यु हो गई, लेकिन शुक्र है जिस तरह से वापस मशीन उसे संग्रहीत कर दिया था।


धन्यवाद! मैं अब एक साल से गेटअप का उपयोग कर खुशी-खुशी कर रहा हूं, लेकिन मुझे गेटटॉप पर भी एक नजर होगी।
tttppp

1
अफसोस की बात है, द 60 सेकेंड गेटअप ट्यूटोरियल का लिंक मर चुका है; ऐसा लगता है कि bashcurescancer.com अब और नहीं है। यहां वेबैक मशीन के संस्करण का लिंक दिया गया है ।
jeffbyrnes


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