web-dev-qa-db-fra.com

Comment puis-je ajouter une méthode d'aide à un script Shell?

Comment puis-je vérifier si un -h attribut a été passé dans un script shell? Je souhaite afficher un message d'aide lorsqu'un utilisateur appelle myscript.sh -h.

111
tttppp

voici un exemple pour 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))

Pour utiliser ceci dans une fonction:

  • utilisez "$FUNCNAME" au lieu de $(basename "$0")
  • ajoutez local OPTIND OPTARG avant d'appeler getopts
147
glenn jackman

Le premier argument d'un script Shell est disponible en tant que variable $1, donc la mise en œuvre la plus simple serait

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

Mais ce qu'a dit Anubhava.

41
seb

voici une partie que je l'utilise pour démarrer un serveur 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
;;

C’est un peu bizarre d’avoir placé l’arrêt, le redémarrage, dans un cas séparé, mais cela devrait fonctionner.

24
Vincent Stans

Si vous n'avez qu'une seule option à vérifier et que ce sera toujours la première option ($1) alors l’option la plus simple est un if avec un test ([). Par exemple:

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

Notez que pour la compatibilité posix = fonctionnera aussi bien que ==.

La raison pour laquelle le $1 doit être mis entre guillemets, c’est que s’il n’ya pas de $1 alors le shell essaiera de lancer if [ == "-h" ] et échouent parce que == n’a reçu qu’un seul argument alors qu’il en attendait deux:

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

Comme suggéréparautres , si vous avez plus d'une simple option, ou si vous avez besoin de vos options pour accepter les arguments, alors vous devriez absolument aller pour la complexité supplémentaire liée à l'utilisation de getopts. Comme référence rapide, j'aime bien Le tutoriel de 60 secondes sur getopts .

Vous pouvez également envisager le programme getopt au lieu du shell intégré getopts . Il permet l’utilisation d’options longues et d’options après des arguments non option (par exemple, foo a b c -v plutôt que simplement foo -v a b c). Cette réponse Stackoverflow explique comment utiliser GNU getopt.

jeffbyrnes indique que le lien d'origine est mort, mais heureusement, la machine de retour l'a archivée.

14
Mark Booth

Mieux vaut utiliser getopt facility de bash. Consultez cette FAQ pour obtenir de l'aide supplémentaire: tilisation de getopts dans le script shell bash pour obtenir des options de ligne de commande longues et courtes

5
anubhava