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.