variable bashrc command-line process environment-variables argument-passing spawn

command-line - bashrc - set environment variable redhat



Estrategia de paso de argumentos-variables de entorno vs. lĂ­nea de comando (3)

La mayoría de las aplicaciones que los desarrolladores escribimos deben estar parametrizadas externamente al inicio. Pasamos rutas de archivos, nombres de tuberías, direcciones TCP / IP, etc. Hasta ahora he estado usando la línea de comandos para pasarlas a la aplicación que se está iniciando. Tuve que analizar la línea de comandos en main y dirigir los argumentos a donde se necesitan, lo que por supuesto es un buen diseño , pero es difícil de mantener para una gran cantidad de argumentos. Recientemente he decidido utilizar el mecanismo de variables de entorno . Son globales y accesibles desde cualquier lugar, lo cual es menos elegante desde el punto de vista arquitectónico, pero limita la cantidad de código .

Estas son mis primeras (y posiblemente muy poco profundas) impresiones sobre ambas estrategias, pero me gustaría escuchar las opiniones de desarrolladores más experimentados. ¿Cuáles son los altibajos de usar variables de entorno y argumentos de línea de comandos para pasar argumentos a un proceso? Me gustaría tener en cuenta los siguientes asuntos:

  1. calidad de diseño (flexibilidad / mantenibilidad),
  2. restricciones de memoria,
  3. portabilidad de la solución.

Observaciones:

Anuncio. 1. Este es el aspecto principal que me interesa.

Anuncio. 2. Esto es un poco pragmático. Conozco algunas limitaciones en Windows que actualmente son huge (más de 32 KB para la línea de comandos y el bloque de entorno). Sin embargo, creo que esto no es un problema, ya que solo debes usar un archivo para pasar toneladas de argumentos si es necesario.

Anuncio. 3. No sé casi nada de Unix, así que no estoy seguro de si ambas estrategias son tan útiles como las de Windows. Elaborar sobre esto si lo desea.


1) Recomendaría evitar las variables ambientales lo más posible.

Ventajas de las variables ambientales.

  • Fácil de usar porque son visibles desde cualquier lugar. Si muchos programas independientes necesitan información, este enfoque es mucho más conveniente.

Contras de variables ambientales

  • Es difícil de usar correctamente porque son visibles (se pueden eliminar, se pueden configurar) desde cualquier lugar. Si instalo un nuevo programa que se basa en variables ambientales, ¿van a pisar mis existentes? ¿Me equivoqué inadvertidamente mis variables ambientales cuando estuve dando vueltas ayer?

Mi opinión

  • use argumentos de la línea de comando para aquellos argumentos que probablemente sean diferentes para cada invocación individual del programa (es decir, n para un programa que calcula n!)
  • use los archivos de configuración para los argumentos que un usuario podría querer cambiar razonablemente, pero no muy a menudo (es decir, el tamaño de la pantalla cuando aparece la ventana)
  • use las variables ambientales con moderación, preferiblemente solo para los argumentos que se espera que no cambien (es decir, la ubicación del intérprete de Python)
  • su punto They are global and accessible from anywhere, which is less elegant from architectural point of view, but limits the amount of code me recuerda las justificaciones para el uso de variables globales;)

Mis cicatrices de experimentar de primera mano los horrores del uso excesivo variable ambiental

  • dos programas que necesitamos en el trabajo, que no pueden ejecutarse en la misma computadora al mismo tiempo debido a choques ambientales
  • Varias versiones de programas con el mismo nombre pero diferentes errores: llevaron a un taller entero de rodillas durante horas porque la ubicación del programa se extrajo del entorno y fue (silenciosa y sutilmente) incorrecta.

2) Límites

Si estuviera superando los límites de lo que puede contener la línea de comandos o de lo que puede manejar el entorno, lo refactorizaré de inmediato.

He usado JSON en el pasado para una aplicación de línea de comandos que necesitaba muchos parámetros. Fue muy conveniente poder usar diccionarios y listas, junto con cadenas y números. La aplicación solo tomó un par de argumentos de línea de comando, uno de los cuales era la ubicación del archivo JSON.

Ventajas de este enfoque.

  • no tenía que escribir mucho código (doloroso) para interactuar con una biblioteca CLI; puede ser difícil conseguir que muchas de las bibliotecas comunes apliquen restricciones complicadas (me refiero a "más complicado" que a la comprobación de un clave específica o alternancia entre un conjunto de claves)
  • no tiene que preocuparse por los requisitos de las bibliotecas CLI para el orden de los argumentos, ¡solo use un objeto JSON!
  • fácil de representar datos complicados (respuesta What won''t fit into command line parameters? ) como listas
  • fácil de usar los datos de otras aplicaciones, tanto para crear como para analizar mediante programación
  • fácil de acomodar futuras extensiones

Nota : quiero distinguir esto del enfoque de archivo .config, no es para almacenar la configuración del usuario. Tal vez debería llamar a esto el enfoque de ''archivo de parámetros de línea de comando'', porque lo uso para un programa que necesita muchos valores que no encajan bien en la línea de comando.

3) Portabilidad de la solución: no sé mucho acerca de las diferencias entre Mac, PC y Linux con respecto a las variables ambientales y los argumentos de la línea de comando, pero puedo decirle:

  • Los tres tienen soporte para variables ambientales.
  • todos soportan argumentos de línea de comando

Sí, lo sé, no fue de mucha ayuda. Lo siento. Pero el punto clave es que puede esperar que una solución razonable sea portátil, aunque definitivamente querrá verificar esto para sus programas (por ejemplo, ¿son las mayúsculas y minúsculas en cualquier plataforma? ¿En todas las plataformas? No sé ).

Un último punto:

Como mencionó Tomasz, no debería importar a la mayoría de las aplicaciones de donde provienen los parámetros.


Creo que esta pregunta ya ha sido respondida bastante bien, pero creo que merece una actualización de 2018. Siento que un beneficio no mencionado de las variables ambientales es que generalmente requieren menos código de placa de caldera para trabajar. Esto hace que el código más legible más limpio. Sin embargo, una desventaja importante es que eliminan capas de aislamiento de diferentes aplicaciones que se ejecutan en la misma máquina. Creo que aquí es donde realmente brilla Docker. Mi patrón de diseño favorito es utilizar exclusivamente variables de entorno y ejecutar la aplicación dentro de un contenedor Docker. Esto elimina el problema de aislamiento.


Debes resumir los parámetros de lectura usando el patrón de Strategy . Cree una abstracción llamada ConfigurationSource tenga readConfig(key) -> value método de readConfig(key) -> value (o que devuelva algún objeto / estructura de Configuration ) con las siguientes implementaciones:

  • CommandLineConfigurationSource
  • EnvironmentVariableConfigurationSource
  • WindowsFileConfigurationSource : carga desde un archivo de configuración desde C:/Document and settings...
  • WindowsRegistryConfigurationSource
  • NetworkConfigrationSource
  • UnixFileConfigurationSource - - cargando desde un archivo de configuración desde /home/user/...
  • DefaultConfigurationSource - por defecto
  • ...

También puede usar el patrón de Cadena de responsabilidad para encadenar fuentes en varias configuraciones como: si no se proporciona el argumento de la línea de comandos, pruebe la variable de entorno y si todo lo demás falla, devuelva los valores predeterminados.

Anuncio 1. Este enfoque no solo le permite abstraer la configuración de lectura, sino que también puede cambiar fácilmente el mecanismo subyacente sin afectar el código del cliente. También puede usar varias fuentes a la vez, retrocediendo o recopilando configuraciones de diferentes fuentes.

Anuncio 2. Simplemente elija la implementación que sea adecuada. Por supuesto, algunas entradas de configuración no caben, por ejemplo, en los argumentos de la línea de comandos.

Anuncio 3. Si algunas implementaciones no son portátiles, tenga dos, una ignorada / omitida silenciosamente cuando no sea adecuada para un sistema dado.