Séparés par des espaces (par exemple, --option argument
)
cat >/tmp/demo-space-separated.sh <<'EOF'
#!/bin/bash
POSITIONAL_ARGS=()
while [[ $# -gt 0 ]]; do
case $1 in
-e|--extension)
EXTENSION="$2"
shift # past argument
shift # past value
;;
-s|--searchpath)
SEARCHPATH="$2"
shift # past argument
shift # past value
;;
--default)
DEFAULT=YES
shift # past argument
;;
-*|--*)
echo "Unknown option $1"
exit 1
;;
*)
POSITIONAL_ARGS+=("$1") # save positional arg
shift # past argument
;;
esac
done
set -- "${POSITIONAL_ARGS[@]}" # restore positional parameters
echo "FILE EXTENSION = ${EXTENSION}"
echo "SEARCH PATH = ${SEARCHPATH}"
echo "DEFAULT = ${DEFAULT}"
echo "Number files in SEARCH PATH with EXTENSION:" $(ls -1 "${SEARCHPATH}"/*."${EXTENSION}" | wc -l)
if [[ -n $1 ]]; then
echo "Last line of file specified as non-opt/last argument:"
tail -1 "$1"
fi
EOF
chmod +x /tmp/demo-space-separated.sh
/tmp/demo-space-separated.sh -e conf -s /etc /etc/hosts
Résultat du copier-coller du bloc ci-dessus
FILE EXTENSION = conf
SEARCH PATH = /etc
DEFAULT =
Number files in SEARCH PATH with EXTENSION: 14
Last line of file specified as non-opt/last argument:
#93.184.216.34 example.com
Utilisation
demo-space-separated.sh -e conf -s /etc /etc/hosts
Bash Equals-Separated (par exemple, --option=argument
)
cat >/tmp/demo-equals-separated.sh <<'EOF'
#!/bin/bash
for i in "$@"; do
case $i in
-e=*|--extension=*)
EXTENSION="${i#*=}"
shift # past argument=value
;;
-s=*|--searchpath=*)
SEARCHPATH="${i#*=}"
shift # past argument=value
;;
--default)
DEFAULT=YES
shift # past argument with no value
;;
-*|--*)
echo "Unknown option $i"
exit 1
;;
*)
;;
esac
done
echo "FILE EXTENSION = ${EXTENSION}"
echo "SEARCH PATH = ${SEARCHPATH}"
echo "DEFAULT = ${DEFAULT}"
echo "Number files in SEARCH PATH with EXTENSION:" $(ls -1 "${SEARCHPATH}"/*."${EXTENSION}" | wc -l)
if [[ -n $1 ]]; then
echo "Last line of file specified as non-opt/last argument:"
tail -1 $1
fi
EOF
chmod +x /tmp/demo-equals-separated.sh
/tmp/demo-equals-separated.sh -e=conf -s=/etc /etc/hosts
Résultat du copier-coller du bloc ci-dessus
FILE EXTENSION = conf
SEARCH PATH = /etc
DEFAULT =
Number files in SEARCH PATH with EXTENSION: 14
Last line of file specified as non-opt/last argument:
#93.184.216.34 example.com
Utilisation
demo-equals-separated.sh -e=conf -s=/etc /etc/hosts
Pour mieux comprendre ${i#*=}
rechercher "Substring Removal" dans ce guide . Il est fonctionnellement équivalent à `sed 's/[^=]*=//' <<< "$i"`
qui appelle un sous-processus inutile ou `echo "$i" | sed 's/[^=]*=//'`
qui appelle deux des sous-processus inutiles.
Utiliser bash avec getopt[s]
Les limitations de getopt(1) (plus anciennes, relativement récentes) getopt
) :
- ne peut pas gérer les arguments qui sont des chaînes vides
- ne peut pas gérer les arguments avec des espaces blancs incorporés
Plus récent getopt
n'ont pas ces limitations. Pour plus d'informations, consultez ces docs .
POSIX getopts
En outre, le shell POSIX et d'autres offrent getopts
qui n'a pas ces limitations. J'ai inclus un exemple simpliste de getopts
exemple.
cat >/tmp/demo-getopts.sh <<'EOF'
#!/bin/sh
# A POSIX variable
OPTIND=1 # Reset in case getopts has been used previously in the shell.
# Initialize our own variables:
output_file=""
verbose=0
while getopts "h?vf:" opt; do
case "$opt" in
h|\?)
show_help
exit 0
;;
v) verbose=1
;;
f) output_file=$OPTARG
;;
esac
done
shift $((OPTIND-1))
[ "${1:-}" = "--" ] && shift
echo "verbose=$verbose, output_file='$output_file', Leftovers: $@"
EOF
chmod +x /tmp/demo-getopts.sh
/tmp/demo-getopts.sh -vf /etc/hosts foo bar
Résultat du copier-coller du bloc ci-dessus
verbose=1, output_file='/etc/hosts', Leftovers: foo bar
Utilisation
demo-getopts.sh -vf /etc/hosts foo bar
Les avantages de getopts
sont :
- Il est plus portable, et fonctionnera dans d'autres coquilles comme
dash
.
- Il peut gérer plusieurs options uniques comme
-vf filename
de la manière typique d'Unix, automatiquement.
L'inconvénient de getopts
est qu'il ne peut traiter que les options courtes ( -h
pas --help
) sans code supplémentaire.
Il existe un tutoriel getopts qui explique la signification de toutes les syntaxes et variables. Dans bash, il y a aussi help getopts
ce qui pourrait être instructif.
2 votes
Pour les utilisateurs de zsh, il existe un excellent utilitaire appelé zparseopts qui peut le faire :
zparseopts -D -E -M -- d=debug -debug=d
Et avoir les deux-d
y--debug
dans le$debug
tableauecho $+debug[1]
retournera 0 ou 1 si l'un d'entre eux est utilisé. Réf : zsh.org/mla/utilisateurs/2011/msg00350.html4 votes
Très bon tutoriel : linuxcommand.org/lc3_wss0120.php . J'aime particulièrement l'exemple "Options de la ligne de commande".
0 votes
J'ai créé un script qui le fait pour vous, il s'appelle - github.com/unfor19/bargs
2 votes
Voir aussi Donner à un bash script la possibilité d'accepter des drapeaux, comme une commande ? pour un analyseur d'options élaboré, ad hoc, long et court. Il ne tente pas de gérer les arguments d'option attachés aux options courtes, ni les options longues avec
=
séparer le nom de l'option de la valeur de l'option (dans les deux cas, il suppose simplement que la valeur de l'option se trouve dans l'argument suivant). Il ne gère pas non plus le regroupement des options courtes - la question n'en avait pas besoin.0 votes
Ce super tutoriel de Baeldung montre 4 façons de traiter les arguments de la ligne de commande dans bash, y compris : 1) les paramètres positionnels
$1
,$2
etc., 2) les drapeaux avecgetopts
y${OPTARG}
3) le passage en boucle de tous les paramètres ($@
), et 4) boucler sur tous les paramètres en utilisant$#
,$1
et leshift
opérateur.