Bir kabuk betiğine nasıl yardım yöntemi ekleyebilirim?


Yanıtlar:


173

İşte bash için bir örnek:

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))

Bunu bir işlev içinde kullanmak için:

  • "$FUNCNAME"yerine kullan$(basename "$0")
  • local OPTIND OPTARGaramadan önce eklegetopts

1
Bunu bir işlevin içinde deniyorum, ancak işlevi çalıştırmayı denediğimde "basename: geçersiz seçenek - 'b" "hatasını alıyorum. basenameÖnde gelen tireyle "-bash" i geçmeye çalışıyor gibi görünüyor .
— Morgan Estes

5
Bir fonksiyon kullanımını imside "$FUNCNAME"değil "$0". Ayrıca, ekleyinlocal OPTIND OPTARG
— glenn jackman

Teşekkürler. FUNCNAMEİşler. Tüm işlevlerim tek bir dosyada var, bu yüzden bu, onları başkaları için yararlı bir şeye genişletmek için mükemmel.
— Morgan Estes

5
@sigur, kullandığınız "$usage" her yerden alıntı yaptığınızdan emin olun .
— glenn jackman

1
Ne shift $((OPTIND - 1))için?
— hpaknia

45

Bir kabuk betiğinin ilk argümanı değişken olarak mevcuttur $1, bu nedenle en basit uygulama

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

Ama anubhava ne dedi.


Teşekkürler @MarkBooth, yazım hatası düzeltildi (artı tırnak işaretlerini sararak iyileştirme)
— seb

Bir değişkenin kötü bir şekilde ayrıştırılmasını önlemek için koşul ifadeleri
— JREAM

2
Evet, OP'nin bash belirtmemesine ve [POSIX uyumlu sürüm olmasına rağmen .
— seb

Not - İçeride kullanmak için function: İşlevinizi çalıştırdıktan sonra kabuğunuzu sonlandırmak istemiyorsanız exit 0ile değiştirmelisiniz return. (Daha önce yaptım 😂)
— Illuminator

29

işte bir VNC sunucusu başlatmak için kullandığım bir bölüm

#!/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

Başlatma durdurma yeniden başlatmayı ayrı bir davaya yerleştirmem biraz garip ama çalışmalı


-d'ye boş bir seçenek verirseniz; sonsuz döngü olmayacak mı?
— zerobane

Yardımcı işlevde neden 1'den çıkıyorsunuz?
— jeantimex

17

Hızlı tek seçenekli bir çözüm için kullanın if

Kontrol etmek için yalnızca tek bir seçeneğiniz varsa ve bu her zaman ilk seçenek ( $1) olacaksa, o zaman en basit çözüm ifbir test ile ( [) kullanmaktır. Örneğin:

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

Posix uyumluluğunun =da işe yarayacağını unutmayın ==.

Neden alıntı yapmalısınız $1?

$1Tırnak içine alınması gerekliliğinin nedeni, eğer hayır yoksa, $1o zaman kabuğun çalışmaya if [ == "-h" ]ve başarısız olmaya çalışacak olmasıdır ==, çünkü iki tane beklerken yalnızca tek bir argüman verilmiştir:

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

Daha karmaşık kullanım için getoptveyagetopts

Gibi önerilen tarafından başkalarına bir argüman kabul edecek seçeneği tek basit seçenekten daha fazla varsa, ya da gerekiyorsa, o zaman kesinlikle kullanmanın ekstra karmaşıklığı için gitmeli getopts.

Hızlı bir referans olarak, 60 saniyelik getopts eğitimini beğendim . †

getoptYerleşik kabuk yerine programı da düşünmek isteyebilirsiniz getopts. Uzun seçeneklerin ve seçenek olmayan argümanlardan sonraki seçeneklerin kullanımına izin verir (örneğin foo a b c --verbose, sadece yerine foo -v a b c). Bu Stackoverflow yanıtı , GNU'nun nasıl kullanılacağını açıklar getopt.

† jeffbyrnes orijinal bağlantının öldüğünden bahsetti, ancak neyse ki makinenin geri dönüş yolu onu arşivledi.


Teşekkürler! Bir yıldır mutlu bir şekilde getopts kullanıyorum, ancak getopt'a da bir göz atacağım.
— tttppp

1
Ne yazık ki, The 60 Second getopts Tutorial ile bağlantı kesildi; Görünüşe göre bashcurescancer.com artık yok. Wayback Machine sürümüne bir bağlantı burada .
— jeffbyrnes


-1

Bunun için davayı kullanabileceğinizi düşünüyorum ...

case $1 in 
 -h) echo $usage ;; 
  h) echo $usage ;;
help) echo $usage ;;
esac
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.