Articulo de referencia

obteneropt

`getopt()` es una función POSIX de C que se utiliza para analizar las opciones de línea de comandos del estilo Unix/POSIX en C. Forma parte de la especificación POSIX y es unive...

`getopt()` es una función POSIX de C que se utiliza para analizar las opciones de línea de comandos del estilo Unix/POSIX en C. Forma parte de la especificación POSIX y es universal para sistemas tipo Unix . También es el nombre de un programa de Unix para analizar los argumentos de la línea de comandos en scripts de shell.

Historia

Un problema de larga data con los programas de línea de comandos era cómo especificar opciones; los primeros programas usaban muchas formas de hacerlo, incluyendo opciones de un solo carácter ( -a), múltiples opciones especificadas juntas ( -abces equivalente a -a -b -c), opciones de varios caracteres ( -inum), opciones con argumentos ( -a arg, -inum 3, -a=arg) y diferentes caracteres de prefijo ( -a, +b, /c).

La función getopt se diseñó como un mecanismo estándar que todos los programas pudieran usar para analizar las opciones de la línea de comandos, de modo que existiera una interfaz común en la que todos pudieran confiar. Por ello, los autores originales seleccionaron, entre las variantes, la compatibilidad con opciones de un solo carácter, opciones múltiples especificadas juntas y opciones con argumentos ( o ), todas controlables mediante una cadena de opciones.-a arg-aarg

getopt data de al menos 1980 [ 1 ] y fue publicado por primera vez por AT&T en la conferencia UNIFORUM de 1985 en Dallas, Texas, con la intención de que estuviera disponible en el dominio público. [ 2 ] Posteriormente, otras variantes de Unix ( 4.3BSD , Linux , etc.) adoptaron versiones del mismo . Está especificado en el estándar POSIX.2 como parte del archivo de cabecera unistd.h . Se han creado derivados de getopt para muchos lenguajes de programación para analizar las opciones de la línea de comandos.

Una función complementaria estándar POSIX para getopt[ 3 ] es getsubopt. [ 4 ] Analiza una cadena de subopciones separadas por comas. Apareció en 4.4BSD (1995). [ 5 ]

Extensiones

getopt es una función dependiente del sistema, y ​​su comportamiento depende de la implementación en la biblioteca C. Sin embargo, existen algunas implementaciones personalizadas como gnulib . [ 6 ]

El manejo convencional (POSIX y BSD) consiste en que las opciones finalizan cuando se encuentra el primer argumento que no es una opción, y que getopt devuelve -1 para indicarlo. Sin embargo, en la extensión de glibc , las opciones se permiten en cualquier lugar para facilitar su uso; getopt permuta implícitamente el vector de argumentos, por lo que aún deja los argumentos que no son opciones al final. Dado que POSIX ya tiene la convención de devolver -1 y omitirlo, siempre se puede usar de forma portable como un indicador de fin de opciones. [ 6 ]--

Una extensión de GNU , getopt_long , permite analizar opciones de varios caracteres más legibles, que se introducen con dos guiones en lugar de uno. La elección de dos guiones permite --inumdiferenciar las opciones de varios caracteres ( ) de las opciones de un solo carácter especificadas juntas ( -abc). La extensión de GNU también permite un formato alternativo para opciones con argumentos: --name=arg. [ 6 ] Esta interfaz resultó popular y ha sido adoptada (sin la permutación) por muchas distribuciones BSD, incluidas FreeBSD y Solaris . [ 7 ] Una forma alternativa de admitir opciones largas se ve en Solaris y Korn Shell (extendiendo optstring ), pero no fue tan popular. [ 8 ]

Otra extensión avanzada común de getopt es el restablecimiento del estado del análisis de argumentos; esto resulta útil como reemplazo de la extensión options-anyware de GNU, o como una forma de "capa" una interfaz de línea de comandos con diferentes opciones en distintos niveles. Esto se logra en sistemas BSD mediante una variable optreset , y en sistemas GNU estableciendo optind en 0. [ 6 ]

Uso

Para usuarios

La sintaxis de línea de comandos para programas basados ​​en getopt es la sintaxis de argumentos de utilidad recomendada por POSIX. En resumen: [ 9 ]

  • Las opciones son caracteres alfanuméricos de una sola letra precedidos por un -guion (-).
  • Las opciones pueden incluir un argumento, obligatorio u opcional, o ninguno.
  • Para especificar que una opción acepta un argumento, incluya :después del nombre de la opción (solo durante la especificación inicial).
  • Cuando una opción toma un argumento, este puede estar en el mismo token o en el siguiente. En otras palabras, si otoma un argumento, -ofooes lo mismo que -o foo.
  • Se pueden encadenar varias opciones, siempre que las que no sean la última no tomen argumentos. Si ay bno toman argumentos mientras que etoma un argumento opcional, -abees lo mismo que -a -b -e, pero -beano es lo mismo que -b -e adebido a la regla anterior.
  • Todas las opciones preceden a los argumentos que no son opciones (excepto en la extensión GNU). --siempre marca el final de las opciones.

Las extensiones de la sintaxis incluyen la convención GNU y la especificación CLIP de Sun. [ 10 ] [ 11 ]

Para programadores

El manual de getopt de GNU especifica dicho uso para getopt() : [ 12 ]

#include <unistd.h>int getopt ( int argc , char * const argv [], const char * optstring );

Aquí, argcy argvse definen exactamente como en el mainprototipo de función de C ; es decir, argcindica la longitud del argvarray de cadenas de C. Contiene optstringuna especificación de qué opciones buscar (alfabetos normales excepto W), y qué opciones aceptar argumentos (dos puntos). Por ejemplo, "vf::o:"se refiere a tres opciones: una sin argumentos v, un argumento opcional fy un argumento obligatorio o. GNU implementa aquí una Wextensión para sinónimos de opciones largas. [ 12 ]

getoptDevuelve un valor intque es una opción charo -1un valor para el final de las opciones. [ 12 ] La práctica habitual es usar un whilebucle para recorrer las opciones y una switchinstrucción casepara seleccionar y actuar sobre ellas. Consulte la sección de ejemplos de este artículo.

Para comunicar información adicional al programa, externeste hace referencia a algunas variables globales para obtener información de ellas getopt:

extern char * optarg ; extern int optind ; extern int opterr ; extern int optopt ;
  • optarg: Un puntero al argumento de la opción actual, si está presente. Se puede usar para controlar dónde comenzar el análisis (nuevamente).
  • optind: ¿Dónde getoptestá mirando actualmente en argv.
  • opterr: Un interruptor booleano que controla si getopt debe imprimir mensajes de error.
  • optopt: Si se produce una opción no reconocida, el valor de ese carácter no reconocido.

La getopt_longinterfaz de extensión de GNU es similar, aunque pertenece a un archivo de cabecera diferente y acepta una opción adicional para definir los nombres "cortos" de las opciones largas y algunos controles adicionales. Si no se define un nombre corto, getoptse colocará en el puntero un índice que haga referencia a la estructura de la opción longindex. [ 12 ]

#include <getopt.h>int getopt_long ( int argc , char * const argv [], const char * optstring , const struct option * longopts , int * longindex );

Ejemplos

Utilizando el estándar POSIX getopt()

#include <stdio.h> #include <stdlib.h> #include <unistd.h>int main ( int argc , char * argv []) { int c ; int digit_optind = 0 ; int opt_a = 0 ; int opt_b = 0 ; char * opt_c = NULL ; char * opt_d = NULL ; while (( c = getopt ( argc , argv , "abc:d:012" )) != -1 ) { int this_option_optind = optind || 1 ; switch ( c ) { case '0' : case '1' : case '2' : if ( digit_optind != 0 && digit_optind != this_option_optind ) { printf ( "Los dígitos aparecen en dos elementos diferentes de argv. \n " ); } digit_optind = this_option_optind ; printf ( "Opción %c \n " , c ); break ; case 'a' : printf ( "opción a \n " ); opt_a = 1 ; break ; case 'b' : printf ( "opción b \n " ); opt_b = 1 ; break ; case 'c' : printf ( "opción c con valor '%s' \n " , optarg ); opt_c = optarg ; break ; case 'd' : printf ( "opción d con valor '%s' \n " , optarg ); opt_d = optarg ; break ; case '?' :break ; default :printf ( "?? getopt devolvió el código de carácter 0%o ?? \n " , c ); } } if ( optind < argc ) { printf ( "Elementos ARGV que no son opciones: " ); while ( optind < argc ) { printf ( "%s" , argv [ optind ++ ]); } printf ( " \n " ); } return 0 ; }

Usando la extensión GNU getopt_long

#include <stdio.h> #include <stdlib.h> #include <getopt.h>typedef struct option Option ;int principal ( int argc , char * argv []) { int c ; int dígito_optind = 0 ; int aopt = 0 ; intbopt = 0 ;char * copto = 0 ; char * punto = 0 ; // Diseño de opciones: Nombre, Argumento, Bandera, Nombre corto static Option long_options [] = { { "add" , required_argument , NULL , 0 }, { "append" , no_argument , NULL , 0 }, { "delete" , required_argument , NULL , 0 }, { "verbose" , no_argument , NULL , 0 }, { "create" , required_argument , NULL , 'c' }, { "file" , required_argument , NULL , 0 }, { NULL , 0 , NULL , 0 } }; int option_index = 0 ; while (( c = getopt_long ( argc , argv , "abc:d:012" , long_options , & option_index )) != -1 ) { int this_option_optind = optind ? optind : 1 ; switch ( c ) { case 0 : printf ( "opción %s" , long_options [ option_index ]. name ); if ( optarg ) { printf ( " con arg %s" , optarg ); } printf ( " \n" ); break ; case '0' : case '1' : case '2' : if ( digit_optind != 0 && digit_optind != this_option_optind ) { printf ( "Los dígitos aparecen en dos elementos argv diferentes. \n " ); } digit_optind = this_option_optind ; printf ( "Opción %c \n " , c ); break ; case 'a' : printf ( "Opción a \n " ); aopt = 1 ; break ; case 'b' : printf ( "Opción b \n " ); bopt = 1 ; break ; case 'c' : printf ( "Opción c con valor '%s' \n " , optarg ); copt = optarg ; break ; case 'd' : printf ( "Opción d con valor '%s' \n " , optarg ); dopt = optarg ; break ; case '?' : break ; default : printf ( "?? getopt devolvió el código de carácter 0%o ?? \n " , c ); } } if ( optind < argc ) { printf ( "Elementos ARGV que no son opciones: " ); while ( optind < argc ) { printf ( "%s " , argv [ optind ++ ]); } printf ( " \n " ); } return 0 ; }

En la concha

Los programadores de scripts de shell suelen querer proporcionar una forma consistente de ofrecer opciones. Para lograrlo, recurren a getopts e intentan adaptarlo a su propio lenguaje de programación.

El primer intento de portabilidad fue el programa getopt , implementado por Unix System Laboratories (USL). Esta versión no podía manejar las comillas ni los metacaracteres de shell, ya que no mostraba ningún intento de usar comillas. Se heredó en FreeBSD. [ 13 ]

En 1986, USL decidió que la falta de seguridad con los metacaracteres y los espacios en blanco ya no era aceptable, y en su lugar creó el comando integrado getopts para la shell Bourne de Unix SVR3 . La ventaja de integrar el comando en la shell es que ahora tiene acceso a las variables de la shell, por lo que los valores se pueden escribir de forma segura sin comillas. Utiliza las variables propias de la shell para rastrear la posición actual y la de los argumentos, OPTIND y OPTARG , y devuelve el nombre de la opción en una variable de shell.

En 1995, getoptsse incluyó en la Especificación UNIX Única versión 1 / Directrices de Portabilidad X/Open Edición 4. [ 14 ] Ahora que forma parte del estándar POSIX Shell, getopts se ha extendido ampliamente en muchos otros shells que intentan ser compatibles con POSIX.

getopt quedó prácticamente en el olvido hasta que util-linux lanzó una versión mejorada que solucionó todos los problemas de la versión anterior mediante el escape de caracteres. También admite los nombres de opciones largas de GNU. [ 15 ] Por otro lado, las opciones largas se han implementado raramente en el getoptscomando en otros intérpretes de comandos, siendo ksh93 una excepción.

En otros idiomas

getopt es una descripción concisa de la estructura común de argumentos de comandos POSIX, y es ampliamente replicada por programadores que buscan proporcionar una interfaz similar, tanto para ellos mismos como para el usuario en la línea de comandos.

  • C no se incluye getopten la biblioteca estándar de C , se llama en sistemas POSIX. gnulib [ 6 ] y MinGW (ambos aceptan el estilo GNU), así como algunas bibliotecas más minimalistas, se pueden usar para proporcionar la funcionalidad. [ 16 ] También existen interfaces alternativas:
    • La poptbiblioteca, utilizada por el gestor de paquetes RPM , tiene la ventaja adicional de ser reentrante .
    • La argpfamilia de funciones de glibc y gnulib proporciona mayor comodidad y modularidad.
  • En C++ , si se ejecuta en un sistema POSIX, se puede llamar getoptde la misma manera que en C.
    • boost::program_optionsLa biblioteca de Boost ofrece una funcionalidad similar.
    • Poco::UtilLas bibliotecas POCO C++ tienen clases Applicationque OptionSetadmiten el análisis de argumentos.
    • Google tiene una biblioteca llamada gflags.
  • C# y .NET Framework : no tienen la funcionalidad getopt en su biblioteca estándar . Hay implementaciones de terceros disponibles, como getopt.net. [ 17 ]
  • D tiene std.getoptun módulo en la biblioteca estándar de D.
  • Go incluye el flagpaquete [ 18 ] , que permite nombres de banderas largos. El getoptpaquete [ 19 ] admite un procesamiento más similar a la función C. También existe otro getoptpaquete [ 20 ] que proporciona una interfaz mucho más parecida a la original de POSIX.
  • Haskell viene con System.Console.GetOpt, que es esencialmente una adaptación a Haskell de la biblioteca GNU getopt. [ 21 ]
  • Java no tiene una implementación de getopt en la biblioteca estándar de Java . Existen varias bibliotecas de código abierto, incluyendo gnu.getopty la Getoptclase, que es portada de GNU getopt, [ 22 ] y Apache Commons CLI. [ 23 ]
  • Lisp tiene muchos dialectos diferentes y no cuenta con una biblioteca estándar común. Existen algunas implementaciones de terceros de getopt para ciertos dialectos de Lisp. Common Lisp cuenta con una implementación de terceros destacada.
  • Free Pascal : tiene su propia implementación como una de sus unidades estándar llamada GetOpts. Es compatible con todas las plataformas.
  • El lenguaje de programación Perl tiene dos derivados separados de getopt en su biblioteca estándar: Getopt::Long[ 24 ] y Getopt::Std. [ 25 ]
  • PHP : tiene una función getopt. [ 26 ]
  • Python contiene un módulo getopten su biblioteca estándar basado en getopt de C y extensiones GNU. [ 27 ] La biblioteca estándar de Python también contiene otros módulos para analizar opciones que son más convenientes de usar. [ 28 ] [ 29 ]
  • Ruby tiene una implementación de getopt_longen su biblioteca estándar, GetoptLong. Ruby también tiene módulos en su biblioteca estándar con una interfaz más sofisticada y conveniente. Existe una implementación de terceros de la interfaz original de getopt.
  • Rust no incluye `getopt` en su biblioteca estándar. La biblioteca clap(llamada así por el análisis de argumentos de línea de comandos) ofrece una funcionalidad similar.

Referencias

  1. "usr/src/lib/libc/pdp11/gen/getopt.c" . Del Sistema III , publicado en junio de 1980, enlazado aquí desde el proyecto The Unix Tree de Warren Toomey. Archivado del original el 12 de mayo de 2023. Consultado el 22 de abril de 2024 .{{cite web}}: CS1 mantenimiento: otros ( enlace )
  2. Quarterman, John (1985-11-03). "Fuente de getopt de AT&T de dominio público" . linux.co.cr (originalmente en el grupo de noticias mod.std.unix) . Archivado del original el 12 de mayo de 2023. Recuperado el 22 de abril de 2024 .
  3. "getopt" (The Open Group Base Specifications Issue 7, edición 2018; IEEE Std 1003.1-2017 (Revisión de IEEE Std 1003.1-2008) ed.). The Open Group . 2018. Archivado del original el 24 de marzo de 2024. Consultado el 22 de abril de 2024 . 
  4. "getsubopt" (The Open Group Base Specifications Issue 7, edición 2018; IEEE Std 1003.1-2017 (Revisión de IEEE Std 1003.1-2008) ed.). The Open Group . 2018. Archivado del original el 2 de diciembre de 2023. Consultado el 22 de abril de 2024 . 
  5. Manual de funciones de la biblioteca de FreeBSDgetsubopt(3)  
  6. 1 2 3 4 5 "getopt" . GNU Gnulib . Consultado el 23 de enero de 2020 .
  7. Manual de funciones de la biblioteca de FreeBSDgetopt_long(3)  
  8. "getopt(3)" . Biblioteca de información de Oracle Solaris 11.2 .
  9. "Convenciones de utilidad" . POSIX.1-2018 .
  10. "Sintaxis de argumentos" . La biblioteca GNU C. Consultado el 24 de enero de 2020 .
  11. David-John, Burrowes; Kowalski III, Joseph E. (22 de enero de 2003). "Especificación CLIP, versión 1.0, PSARC 1999/645" (PDF) . Archivado del original (PDF) el 27 de junio de 2020.
  12. 1 2 3 4Manual de funciones de la biblioteca de Linux de ManKier.comgetopt(3)  
  13. Manual de comandos generales de FreeBSDgetopt(1)  
  14. "getopts" . The Open Group (POSIX 2018) .
  15. Manual de usuario de Linux – Comandos de usuariogetopt(1)  
  16. "visual studio - getopt.h: Compilación de código C de Linux en Windows" . Stack Overflow .
  17. "GNU Getopt .NET" . GitHub .
  18. "Indicador de paquete" .
  19. "Paquete getopt" .
  20. "Paquete getopt" .
  21. "System.Console.GetOpt" .
  22. "Clase gnu.getopt.Getopt" . Consultado el 24 de junio de 2013 .
  23. "Commons CLI" . Apache Commons . Apache Software Foundation. 27 de febrero de 2013. Consultado el 24 de junio de 2013 .
  24. "Getopt::Long - perldoc.perl.org" .
  25. "Getopt::Std - perldoc.perl.org" .
  26. "PHP: getopt - Manual" .
  27. "16.5. getopt — Analizador estilo C para opciones de línea de comandos — Documentación de Python 3.6.0" .
  28. "Analizador para opciones de línea de comandos" . Consultado el 30 de abril de 2013 .Obsoleto desde la versión 2.7
  29. "Analizador para opciones, argumentos y subcomandos de línea de comandos" . Consultado el 30 de abril de 2013 .
  • Especificación POSIX
  • Manual de GNU getopt
  • Versión completa de getopt para proyectos Unicode y Multibyte de Microsoft Visual C, C++ o MFC.
Obtenido de " https://en.wikipedia.org/w/index.php?title=Getopt&oldid=1362588425 "