¿Por qué se pueden omitir espacios entre opciones y parámetros?

16

Por ejemplo:

xargs -n 1

es lo mismo que

xargs -n1

Pero si nos fijamos en la página del manual , la opción aparece como -n max-args, lo que significa que se supone que se debe preservar el espacio. No hay nada sobre la forma abreviada -n max-args .

Esto también sucede con muchas otras utilidades de Linux.

¿Cómo se llama esto en Linux? ¿Todas las utilidades admiten el formulario abreviado (pero nunca lo documentan en la página del manual)?

J.Joe
fuente
1
12.1.2.a es algo de la historia; Juro que ya hay una buena pregunta sobre esto, pero aún no la he encontrado.
2
@drewbenn la otra pregunta que estás pensando podría haber sido mía: unix.stackexchange.com/q/188046/41515

Respuestas:

12

Cuando escribe el bit de análisis de la línea de comando de su código, especifica qué opciones toman argumentos y cuáles no. Por ejemplo, en un script de shell que acepta una -hopción (por ejemplo, ayuda) y una -aopción que debería tomar un argumento, usted

opt_h=0     # default value
opt_a=""

while getopts 'a:h' opt; do
    case $opt in
        h)  opt_h=1 ;;
        a)  opt_a="$OPTARG" ;;
    esac
done

echo "h: $opt_h"
echo "a: $opt_a"

El a:hbit dice "Estoy esperando a analizar dos opciones, -ay -h, y -adebería tener una discusión" (que es el :después de aque le dice al analizador que -atoma un argumento).

Por lo tanto, nunca hay ambigüedad sobre dónde termina una opción, dónde comienza su valor y dónde comienza otra después de eso.

Ejecutándolo:

$ bash test.sh -h -a hello
h: 1
a: hello

$ bash test.sh -h -ahello
h: 1
a: hello

$ bash test.sh -hahello
h: 1
a: hello

Es por eso que la mayoría de las veces no debe escribir su propio analizador de línea de comandos para analizar las opciones.

Solo hay un caso en este ejemplo que es complicado. El análisis generalmente se detiene en la primera no opción, por lo que cuando tiene cosas en la línea de comando que parecen opciones:

$ bash test.sh -a hello -world
test.sh: illegal option -- w
test.sh: illegal option -- o
test.sh: illegal option -- r
test.sh: illegal option -- l
test.sh: illegal option -- d
h: 0
a: hello

Lo siguiente resuelve eso:

$ bash test.sh -a hello -- -world
h: 0
a: hello

Las --señales de una gama de opciones de línea de comandos, y el -worldbit se deja para el programa para hacer lo que quiera con (está en una de las variables de posición).

Así es, por cierto, cómo elimina un archivo que tiene un guión al comienzo de su nombre de archivo rm.

EDITAR :

Utilidades escritas en llamada C getopt()(declarada en unistd.h) que funciona más o menos de la misma manera. De hecho, por lo que sabemos, la bashfunción getoptspuede implementarse usando una llamada a la función de biblioteca C getopt(). Perl, Python y otros lenguajes tienen bibliotecas de análisis de línea de comando similares, y es muy probable que realicen su análisis de manera similar.

Algunos de estos getopty getopt-como rutinas de biblioteca también se encargan de opciones "largos". Estos generalmente están precedidos por doble guión ( --), y las opciones largas que toman argumentos a menudo lo hacen después de un signo igual, por ejemplo, la --block-size=SIZEopción de [algunas implementaciones de] la duutilidad (que también permite -B SIZEespecificar lo mismo).

La razón por la cual los manuales a menudo se escriben para mostrar un espacio entre las opciones cortas y sus argumentos es probablemente para facilitar la lectura.

EDITAR : Las herramientas realmente antiguas, como las utilidades ddy tar, tienen opciones sin guiones delante de ellas. Esto es solo por razones históricas y para mantener la compatibilidad con el software que depende de ellos para funcionar exactamente de esa manera. La tarutilidad ha ganado la capacidad de tomar opciones con guiones en tiempos más recientes. El manual BSD para tarllamar a las opciones de estilo antiguo para "banderas agrupadas".

Kusalananda
fuente
Esta característica puede parecer fácil de implementar en scripts de bash. Pero creo que la mayoría de las utilidades están escritas en C (luego compiladas en binarios) no bash. ¿Por qué estas utilidades implementan esta característica?
J.Joe
@ J.Joe Porque llaman getopt()(declarado en unistd.h), que hace lo mismo.
Kusalananda
2
Sí, tienes razón. Referencia . Esto también resuelve otro misterio de que las opciones se pueden combinar -a -b=== -ab
J.Joe
1
Los argumentos opcionales para las banderas crearían una ambigüedad, por lo que no se pueden combinar (si -atiene un argumento opcional, -abno es lo mismo que -a -b). GNU getopt no detiene el procesamiento de banderas cuando se encuentra con una no bandera: en su lugar (por defecto), en cambio reorganiza las banderas al frente de argv.
ilkkachu
@ilkkachu Gracias por esa aclaración. Puedo actualizar mi respuesta más tarde.
Kusalananda
4

xargses una de las utilidades POSIX. Como comentó @drewbenn, POSIX documenta el comportamiento de análisis de opciones para que coincidan la mayoría de sus utilidades getopt, con algunos permisos para otras implementaciones, diciendo en 12.1 Sintaxis de argumento de utilidad :

Esta sección describe la sintaxis de argumentos de las utilidades estándar e introduce la terminología utilizada en POSIX.1-2008 para describir los argumentos procesados ​​por las utilidades.

En POSIX.1-2008, se usa una notación especial para describir la sintaxis de los argumentos de una utilidad. A menos que se indique lo contrario , todas las descripciones de utilidades utilizan esta notación, que se ilustra en este ejemplo (ver Comandos simples de XCU ):

y concluyendo con

Se recomienda que todas las futuras utilidades y aplicaciones utilicen estas pautas para mejorar la portabilidad del usuario. El hecho de que algunas utilidades históricas no puedan cambiarse (para evitar romper las aplicaciones existentes) no debería disuadir este objetivo futuro.

Dentro de POSIX (recuerde que cubre solo las utilidades más comúnmente utilizadas), hay excepciones que pasan operandos que serían opciones en otras utilidades como parámetros posicionales o parámetros con sintaxis especial :

POSIX permite valores opcionales opcionales:

Los argumentos de opción se muestran separados de sus opciones por <blank>caracteres, excepto cuando el argumento de opción está encerrado en la notación '['y ']'para indicar que es opcional.

Por casualidad, no recuerdo qué utilidades POSIX usan la función. Los ncurses ticy las infocmputilidades utilizan la función para los niveles de la -vopción (detallado / depurar).

El punto específico sobre el que preguntó se detalla en el resto de ese párrafo, en varias líneas.

Antes de POSIX, algunas implementaciones de psopciones aceptadas sin un guión principal. La descripción POSIX no menciona que en la descripción de la utilidad o en la justificación de la sintaxis:

Además de POSIX, hay implementaciones de opciones largas (como GNU getopt_long o X Toolkit ), que utilizan una variedad de formas para separar o unir el valor de una opción a la opción. Por ejemplo, se puede usar la puntuación:

--option=value
--option value

Dependiendo de la implementación, un doble guión puede / no puede usarse para distinguir las opciones largas de las cortas (getopt): lynx y X Toolkit usan un solo guión; GNU getopt_longusa un doble guión, por ejemplo. Además, +se puede usar a para indicar que una opción está negada.

La descripción de POSIX no parece mencionar ninguno de estos, pero es probable que los encuentre.

Thomas Dickey
fuente
Se -option=valuesupone que es --option=value? (El formato de opción larga, dos guiones al principio en lugar de uno)
J.Joe
Algunas utilidades heredadas usan opciones largas de un solo guión (-opción) pero están en gran parte desaprobadas para nuevos scripts y programas. Use un solo guión para las opciones cortas que maneja getopt. Casi todos los scripts y programas nuevos utilizan opciones largas de doble guión. Muchos también admiten equivalentes de opciones cortas de un solo guión para los más utilizados. Las opciones largas hacen que el código del script sea mucho más autodocumentado, ya que necesita menos comentarios.
DocSalvager