¿Por qué estas opciones anidadas en un script de shell POSIX se dividen en palabras?

¿Por qué estas opciones anidadas en un script de shell POSIX se dividen en palabras?

Tengo un script count_argsque cuenta argumentos:

#!/bin/sh
echo $#

Si lo llamo con estas opciones, me dice que obtiene dos argumentos:

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

Pero si construyo los argumentos en un script test_argsasí:

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

... me sale el resultado:

$ ./test_args 
3

¿Por qué el '1 2'ser está dividido en el guión? ¿Cómo puedo evitar esto de forma compatible con POSIX?del script de llamada? ¿Es posible seguir almacenando argumentos en variables de alguna manera para poder separarlos en scripts más complejos (por ejemplo, tener ARGS_1y ARGS_2)?

Tenga en cuenta que mi /bin/shes dash.

Respuesta1

En su primer caso, los argumentos pasados count_args​​fueron interpretados por el shell, el shell vio dos palabras --optionsy 1 2luego se las pasó a count_args.

En el segundo caso, entre comillas dobles, todos los caracteres excepto $y \se tratan como literales. Es demasiado tarde para que el shell interprete las comillas simples, el shell vio el contenido de $ARGSla variable como una cadena larga --options '1 2', todos los caracteres son literales y no tienen ningún significado especial para el shell.

El uso ${ARGS}sin comillas dobles lo hacía sujeto a la división de campos y la expansión del nombre de archivo. Con el valor predeterminado de IFS, tienes tres palabras separadas --options: '1y 2'.

La mejor manera de archivar esto es usando "$@":

#!/bin/sh

set -- --options '1 2'

./count_args "$@"

información relacionada