Wie korrigiere ich das von getopt erhaltene Argument?

Wie korrigiere ich das von getopt erhaltene Argument?

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 2erhalte ich die Fehlermeldung

sleep: invalid time interval `\'2\''

Was mache ich falsch? Wie formatiere ich das Argument richtig?

Antwort1

Das integrierte Bash-Tool getoptsist viel einfacher zu verwenden. Wenn Sie verwenden bash, sollten Sie es anstelle von verwenden getopt.

GNU getoptist 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 getoptsbesser 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 getoptserfordert das integrierte Bash-Element kein evalund 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

verwandte Informationen