Ich habe die folgenden Befehle in meinem Skript:
set -- `getopt -q agvc:l:t:i: "$@"`
...
while [ -n "$1" ]
do
-i) TIME_GAP_BOOT=$2
shift ;;
...
sleep $TIME_GAP_BOOT
Beim Aufrufen des Skripts mit -i 2
erhalte ich die Fehlermeldung
sleep: invalid time interval `\'2\''
Was mache ich falsch? Wie formatiere ich das Argument richtig?
Antwort1
Das integrierte Bash-Tool getopts
ist viel einfacher zu verwenden. Wenn Sie verwenden bash
, sollten Sie es anstelle von verwenden getopt
.
GNU getopt
ist für die Arbeit mit Argumenten konzipiert, die Leerzeichen und andere Metazeichen enthalten. Zu diesem Zweck erzeugt es eine Ergebniszeichenfolge mit Anführungszeichen im Bash-Stil (oder Anführungszeichen im CSH-Stil, je nach Option -s
). Sie müssen dafür sorgen, dass die Anführungszeichen interpretiert werden, was die Verwendung von erfordert eval
. (Habe ich erwähnt, dass das integrierte Bash-Element getopts
besser ist?).
Das folgende Beispiel stammt aus der getopt-Distribution; ich hatte damit nichts zu tun. (Es sollte irgendwo auf Ihrem Rechner vorhanden sein; bei Ubuntu und Debian wird es als angezeigt /usr/share/doc/util-linux/examples/getopt-parse.bash
. Ich zitiere nur ein paar Zeilen:
# Note that we use `"$@"' to let each command-line parameter expand to a
# separate word. The quotes around `$@' are essential!
# We need TEMP as the `eval set --' would nuke the return value of getopt.
TEMP=`getopt -o ab:c:: --long a-long,b-long:,c-long:: \
-n 'example.bash' -- "$@"`
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
# Note the quotes around `$TEMP': they are essential!
eval set -- "$TEMP"
Zusätzlich zu den Anführungszeichen, auf die der Kommentar des Beispiels hinweist, ist es wichtig, auf das zu achten eval
, das im Allgemeinen verpönt ist.
Im Gegensatz dazu getopts
erfordert das integrierte Bash-Element kein eval
und ist ziemlich unkompliziert. Es emuliert im Wesentlichen den Standardaufruf der C-Bibliothek:
while getopts agvc:l:t:i: opt; do
case "$opt" in
i) TIME_GAP_BOOT=$OPTARG;;
# ...
esac
done