Jak sprawdzić, czy -hatrybut został przekazany do skryptu powłoki? Chciałbym wyświetlić komunikat pomocy, gdy dzwoni użytkownik myscript.sh -h.
Odpowiedzi:
oto przykład dla basha:
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))
Aby użyć tego wewnątrz funkcji:
"$FUNCNAME"zamiast$(basename "$0")local OPTIND OPTARGprzed zadzwonieniemgetoptsbasenamez początkowym myślnikiem.
"$FUNCNAME"nie używa "$0". Dodaj teżlocal OPTIND OPTARG
FUNCNAMEPracuje. Mam wszystkie moje funkcje w jednym pliku, więc jest to idealne rozwiązanie do rozszerzenia ich na coś przydatnego dla innych.
"$usage" każde miejsce, w którym go używasz.
shift $((OPTIND - 1))?
Pierwszy argument skryptu powłoki jest dostępny jako zmienna $1, więc najprostsza byłaby implementacja
if [ "$1" == "-h" ]; then
echo "Usage: `basename $0` [somestuff]"
exit 0
fi
Ale co powiedział Anubhava.
[jest wersją zgodną z POSIX.
function: Należy wymienić exit 0ze returnjeśli nie chcesz, aby zakończyć swoją skorupę po uruchomić funkcję. (Robiłem to wcześniej 😂)
tutaj jest część, której używam do uruchomienia serwera 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
To trochę dziwne, że umieściłem start stop restart w osobnym przypadku, ale powinno działać
ifJeśli masz tylko jedną opcję do sprawdzenia i zawsze będzie to pierwsza opcja ( $1), najprostszym rozwiązaniem jest metoda ifz testem ( [). Na przykład:
if [ "$1" == "-h" ] ; then
echo "Usage: `basename $0` [-h]"
exit 0
fi
Zauważ, że dla kompatybilności z posix =zadziała również ==.
$1?Powodem, $1dla którego należy ująć w cudzysłów, jest to, że jeśli nie ma, $1to powłoka spróbuje uruchomić się if [ == "-h" ]i zawiedzie, ponieważ ==otrzymała tylko jeden argument, gdy oczekiwała dwóch:
$ [ == "-h" ]
bash: [: ==: unary operator expected
getoptlubgetoptsJak sugerowano przez innych , jeśli masz więcej niż jedną opcję prostego lub potrzebujesz opcję przyjąć argumentu, to powinno się iść do dodatkowej złożoności użyciu getopts.
Krótko mówiąc, podoba mi się samouczek dotyczący 60 sekund getopts . †
Możesz także rozważyć getoptprogram zamiast wbudowanej powłoki getopts. Pozwala na użycie długich opcji i opcji po argumentach innych niż opcje (np. foo a b c --verboseRaczej niż tylko foo -v a b c). Ta odpowiedź Stackoverflow wyjaśnia, jak używać GNU getopt.
† jeffbyrnes wspomniał, że oryginalny link zgasł, ale na szczęście maszyna zarchiwizowała go.
Lepiej jest użyć funkcji bash w getopt. Proszę spojrzeć na te pytania i odpowiedzi, aby uzyskać dodatkową pomoc: Używanie getopts w skrypcie powłoki bash, aby uzyskać długie i krótkie opcje wiersza poleceń
myślę, że możesz użyć tego przypadku ...
case $1 in
-h) echo $usage ;;
h) echo $usage ;;
help) echo $usage ;;
esac