Warum werden diese verschachtelten Optionen in einem POSIX-Shell-Skript in Wörter aufgeteilt?

Warum werden diese verschachtelten Optionen in einem POSIX-Shell-Skript in Wörter aufgeteilt?

Ich habe ein Skript count_args, das Argumente zählt:

#!/bin/sh
echo $#

Wenn ich es mit diesen Optionen aufrufe, erhalte ich die Meldung, dass es zwei Argumente erhält:

$ ./count_args --options '1 2'
2

Aber wenn ich die Argumente in einem Skript test_argswie folgt konstruiere:

#!/bin/sh
ARGS="--options '1 2'"
./count_args ${ARGS}

...bekomme ich das Ergebnis:

$ ./test_args 
3

Warum wird '1 2'im Skript gespalten? Wie kann ich dies POSIX-konform vermeiden?aus dem aufrufenden Skript? Ist es möglich, Argumente trotzdem irgendwie in Variablen zu speichern, sodass ich sie in komplexeren Skripten (z. B. mit ARGS_1und ARGS_2) trennen kann?

Beachten Sie, dass mein /bin/shist dash.

Antwort1

In Ihrem ersten Fall wurden die an übergebenen Argumente count_argsvon der Shell interpretiert, die Shell hat zwei Wörter gesehen --optionsund 1 2sie dann an übergeben count_args.

Im zweiten Fall werden innerhalb der Anführungszeichen alle Zeichen außer $und \als Literale behandelt. Für die Shell ist es zu spät, die einfachen Anführungszeichen zu interpretieren, da die Shell den Inhalt der $ARGSVariablen als langen String betrachtet hat --options '1 2', alle Zeichen als Literale und haben für die Shell keine besondere Bedeutung.

Die Verwendung ${ARGS}ohne Anführungszeichen führte zu einer Feldaufteilung und Dateinamenerweiterung. Mit dem Standardwert von IFSerhalten Sie drei getrennte Wörter: --options, '1und 2'.

Der beste Weg, dies zu archivieren, ist die Verwendung von "$@":

#!/bin/sh

set -- --options '1 2'

./count_args "$@"

verwandte Informationen