En el entorno C/Unix en el que trabajo, veo algunos desarrolladores que usan __progname en lugar de argv [0] para los mensajes de usage(). ¿Hay alguna ventaja en esto? ¿Cuál es la diferencia entre __progname y argv [0]? ¿Es portátil?Usando '__progname' en lugar de argv [0]
Respuesta
__progname
no es estándar y, por lo tanto, no es portátil, prefiera argv[0]
. Supongo que __progname
podría buscar un recurso de cadena para obtener el nombre que no depende del nombre de archivo con el que lo ejecutó. Pero argv[0]
le dará el nombre que en realidad lo ejecutó como el que me resultaría más útil.
El uso de __progname
le permite modificar el contenido de la matriz argv[]
mientras aún mantiene el nombre del programa. Algunas de las herramientas comunes como getopt()
modifican argv[]
mientras procesan los argumentos.
Para portabilidad, puede strcopy argv[0]
en su propio buffer progname
cuando se inicia el programa.
GNU getopt() se entromete con argv; las versiones que no son GNU generalmente no lo hacen. –
@Jonathan: Sí, gracias por la aclaración. I GNU Me había quedado con una plataforma por mucho tiempo. (Lo siento) –
Es un BSDismo, y definitivamente no portátil.
Si su programa se ejecutó utilizando, por ejemplo, un enlace simbólico, argv [0] contendrá el nombre de ese enlace.
Supongo que __progname contendrá el nombre del archivo de programa real.
En cualquier caso, argv [0] está definido por el estándar C. __progname no es.
Veo al menos dos posibles problemas con argv [0].
Primero, argv [0] o argv en sí mismo pueden ser NULL si execve() llamador fue malvado o descuidado. Llamar a execve ("foobar", NULL, NULL) suele ser una forma fácil y divertida de demostrar que un programador confiado en su código no es a prueba de sig11.
También se debe tener en cuenta que argv no se definirá fuera de main() mientras que __progname generalmente se define como una variable global que puede usar desde dentro de su función use() o incluso antes de llamar a main() (como non constructores estándar de GCC).
Pero "una aplicación POSIX estrictamente conforme para pasar al menos un argumento a la función exec, garantizando así que argc sea uno o más cuando se invoque por una aplicación de este tipo". ¡Seguramente nadie violaría POSIX! (http://www.opengroup.org/onlinepubs/000095399/functions/exec.html) –
También hay una extensión GNU para esto, de modo que se puede acceder al nombre de invocación del programa desde fuera de main() sin guardarlo manualmente. Sin embargo, podría ser mejor hacerlo manualmente; por lo tanto, es portátil en lugar de depender de la extensión de GNU. Sin embargo, aquí proporciono un extracto de la documentación disponible.
De the on-line GNU C Library manual (visitada en la actualidad):.
"Muchos programas que no leen la entrada de la terminal están diseñados para salir si falla cualquier llamada al sistema Por convención, el mensaje de error de un programa de este tipo debe comenzar con . el nombre del programa, sans directorios puede encontrar ese nombre en la variable program_invocation_short_name
, el nombre completo del archivo se almacena la variable program_invocation_name
variable: char * program_invocation_name . El valor de esta variable es el nombre que se utilizó para invocar el programa que se ejecuta en el proceso actual. Es lo mismo que
argv[0]
. Tenga en cuenta que esto no es necesariamente un nombre de archivo útil; a menudo no contiene nombres de directorio.variable: char * program_invocation_short_name valor de esta variable es el nombre que se utiliza para invocar el programa que se ejecuta en el proceso actual, con los nombres de directorio eliminado. (Es decir, es el mismo que
program_invocation_name
menos todo hasta la última barra, si los hubiera.) Código de inicialización
La biblioteca pone en marcha estas dos variables antes de llamar principal.
Portabilidad Nota: Estas dos variables son extensiones de GNU. Si desea que su programa trabaje con bibliotecas que no sean de GNU, debe guardar el valor de argv[0]
en main, y luego quitar los nombres de directorio usted mismo. Agregamos estas extensiones para que sea posible escribir subrutinas de informe de errores independientes que no requieren una cooperación explícita del principal. "
__progname es solo argv [0], y los ejemplos en otras respuestas aquí muestran las debilidades de su uso . Aunque tampoco es portátil, estoy usando readlink en/proc/self/exe (Linux, Android) y leyendo el contenido de/proc/self/exefile (QNX).
- 1. diferencia entre (* ++ argv) [0] y mientras (c = * ++ argv [0])
- 2. Usando argv en C?
- 3. Configuración de argv [0] en Haskell?
- 4. ¿Cuál es el equivalente de argv [0]?
- 5. ¿Puede argv [0] contener una cadena vacía?
- 6. ¿Cuándo puede argv [0] tener nulo?
- 7. ¿Cómo se puede obtener el argv del sistema operativo [0] (no sys.argv [0]) en Python?
- 8. Usando argc y argv en Eclipse?
- 9. curl_errno devuelve 0 en lugar de 6
- 10. $ argv en una clase
- 11. C++ - char ** argv vs char * argv []
- 12. Mostrar `00` en lugar de` 0` en un control NumericUpDown
- 13. argv [argc] ==?
- 14. puntero a puntero con argv
- 15. Configurar Hibernate (usando JPA) para almacenar Y/N para tipo Boolean en lugar de 0/1
- 16. Html.TextboxFor/decimales que se vacía en lugar de 0
- 17. usando // en lugar de protocolo: //
- 18. Sin acceso a argv [0], ¿cómo obtengo el nombre del programa?
- 19. C++ bool devuelve 0 1 en lugar de verdadero falso
- 20. Script para ejecutar contra stdin si no arg; de lo contrario, ingrese el archivo = ARGV [0]
- 21. ¿Por qué 0.ToString ("#. ##") devuelve una cadena vacía en lugar de 0.00 o al menos 0?
- 22. Autoboxing: entonces puedo escribir: Integer i = 0; en lugar de: Integer i = new Integer (0);
- 23. convertir cadena a argv en C++
- 24. un puntero sobre * argv []
- 25. de Windows argv Unicode comandos
- 26. ¿Por qué debería usar <ARGV> o <> en lugar de <STDIN> en Perl?
- 27. argv y calculadora de notación polaca
- 28. 0 + 0 + 0 ... + 0! = 0
- 29. Usando finalmente en lugar de captura
- 30. usando señales boost en lugar de qt
Considere: execl ("/ bin/sh "," hot potatoes "," -c "," echo $ 0 - Hi ", (char *) 0); Funciona bien; argv [0] es" hot potatoes "; se hace eco de" hot potatoes - Hi ". Eso no es nada para hacer con el nombre del ejecutable que se ejecutó. –
A pesar del comentario anterior, estoy de acuerdo en que argv [0] es más portable. Y solo unos pocos programas se mezclan con argv [0] así, pero cualquier atacante puede hacerlo. Tenga cuidado con b Tomando decisiones críticas sobre argv [0]. –