43

La mayoría de las aplicaciones que los desarrolladores escriben deben parametrizarse 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á lanzando. Tuve que analizar la línea de comandos en main y dirigir los argumentos a donde se necesitan, que es por supuesto un buen diseño , pero es difícil de mantener para una gran cantidad de argumentos. Recientemente decidí usar el mecanismo de variables de entorno. Son globales y accesibles desde cualquier lugar, que es menos elegante desde el punto de vista arquitectónico, pero limita la cantidad de código.Estrategia de aprobación de argumentos: variables de entorno frente a la línea de comandos

Estas son mis primeras impresiones (y posiblemente bastante superficiales) en ambas estrategias, pero me gustaría escuchar opiniones de desarrolladores más experimentados: ¿Cuáles son los altibajos del uso de variables de entorno y argumentos de línea de comando para pasar argumentos? a un proceso? que me gustaría tener en cuenta las siguientes cuestiones:

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

Observaciones:

anuncio. 1. Este es el aspecto principal en el que estoy interesado.

Ad. 2. Esto es un poco pragmático. Conozco algunas limitaciones en Windows que actualmente son huge (más de 32kB tanto para la línea de comando como para el bloque de entorno). Supongo que esto no es un problema, ya que solo debes usar un archivo para pasar toneladas de argumentos si lo necesitas.

Ad. 3. No sé casi nada de Unix, así que no estoy seguro de si ambas estrategias son tan utilizables como en Windows. Elabore esto si lo desea.

+0

¿Podría dar más detalles, como en el número real de parámetros? y si hay agrupaciones para ellos o son todos al azar? y para que idioma es esto? java, C++, etc ...La razón por la que estoy pidiendo ese nivel de detalle es que, si bien podría tratarse de un problema en cualquier idioma, puede haber una solución específica para la implementación del idioma de la que no tenga conocimiento. –

+0

Para mencionar los sistemas operativos * nix, no tienen nada que ver con "variable de entorno global" y cada env var se hereda del proceso principal al proceso hijo en el horario de fork. Entonces, "global" no es un pro para env var sobre la línea de comando, al menos para esos sistemas operativos. – shr

+0

Hola, @jamesDrinkard. Estoy interesado en un enfoque general. Si quisiera pasar 20 argumentos diferentes de cadena etiquetada/integral/número real de un script de Python ejecutado por un intérprete de 32 bits a una aplicación de 64 bits escrita en C++, ¿qué método usaría? –

Respuesta

45

1) Yo recomendaría evitar variables ambientales tanto como sea posible.

Pros de variables ambientales

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

contras de las variables ambientales

  • difíciles de usar correctamente porque son visibles (delete-poder, set-poder) desde cualquier lugar. Si instalo un nuevo programa que dependa de variables ambientales, ¿pisarán las existentes? ¿Inadvertidamente arruiné mis variables ambientales cuando estaba monkeando ayer?

Mi opinión

  • uso de argumentos de línea de comandos para los argumentos que tienen más probabilidades de ser diferente para cada llamada individual del programa (es decir, n para un programa que calcula n!)
  • use los archivos de configuración para los argumentos que un usuario razonablemente podría querer cambiar, pero no muy a menudo (es decir, cuando aparece la ventana emergente)
  • use las variables del entorno con moderación, preferiblemente solo para los argumentos que se esperan no cambiar (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 justificaciones para el uso de variables globales;)

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

  • dos programas que necesitamos en el trabajo, que no se pueden ejecutar en la misma computadora al mismo tiempo debido a choques ambientales
  • versiones múltiples de programas con el mismo nombre pero diferentes errores - hermano Todo un taller rodó por horas porque la ubicación del programa fue sacada del entorno y estaba (silenciosa, sutilmente) mal.

2) Límites

Si estuviera empujando los límites de lo que sea la línea de comandos puede contener, o lo que el medio ambiente puede manejar, me refactor inmediatamente.

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 tiene que escribir mucho código (dolorosa) para interactuar con una biblioteca CLI - que puede ser un dolor para conseguir muchas de las bibliotecas comunes a imponer restricciones complicadas (por 'complicado' quiero decir más complejo que buscar una clave específica o alternar 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 JSON ¡objeto!
  • fácil de representar los datos complicados (contestador What won't fit into command line parameters?), tales como listas de
  • fácil de usar los datos de otras aplicaciones - tanto para crear y analizar mediante programación
  • fácil para dar cabida a futuras ampliaciones

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


3) portabilidad solución: No sé mucho acerca de las diferencias entre Mac, PC y Linux con respecto a las variables ambientales y los argumentos de línea de comandos, pero te puedo decir:

  • los tres tienen soporte para las variables ambientales
  • que todos los argumentos de comandos de apoyo de línea

Sí, lo sé - que no era muy útil. Lo siento. Pero el punto clave es que puede esperar una solución razonable para ser portátil, aunque definitivamente querrá verificar esto para sus programas (por ejemplo, ¿son args de línea de comandos sensibles a las mayúsculas y minúsculas en cualquier plataforma? ¿En todas las plataformas? lo sé).


Un último punto:

Como se mencionó Tomasz, no debe importar a la mayoría de la aplicación en la que los parámetros de procedencia.

+0

Gracias, Matt. Este es un tipo de opinión que he estado buscando. El consejo más importante es el uso de variables de entorno para la descripción del entorno de ejecución, que apenas cambia, y el archivo cmd para la ejecución real de argumentos simples/complejos que pasan. Muy racional, gracias. Sin embargo, tenga en cuenta que podría usar variables de entorno 'locales' que solo podrían estropear los procesos secundarios. Es muy similar a los argumentos de línea de comando pasando, excepto lo que Raymond señaló bajo la respuesta de Tomasz. –

+1

Muy buena respuesta! Con respecto a la desventaja de que las variables de entorno se pueden cambiar desde cualquier lugar: también existe la posibilidad de establecer variables de entorno localmente desde un script de inicio (por ejemplo, secuencia de comandos Bash o Batch) para la aplicación. En ese caso, puede haber un valor predeterminado en todo el sistema, pero una aplicación puede, si es necesario, cambiar el valor predeterminado a un valor personalizado. ¿Cuáles son sus pensamientos sobre eso? – Lii

+0

¿Existen ventajas y desventajas al considerar cómo pasar secretos/credenciales? – iamyojimbo

3

Debe abstraer los parámetros de lectura usando el patrón Strategy. Crear una abstracción nombrado ConfigurationSource tener readConfig(key) -> value método (o devolver algunos Configuration objeto/estructura) con implementaciones siguientes:

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

También puede utilizar Chain of responsibility patrón para las fuentes de la cadena en varias configuraciones como: si el argumento de línea de comandos no se suministra, tratar variable de entorno y si todo lo demás falla, defauls volver.

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 se adaptarán, por ejemplo, a los argumentos de línea de comando.

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

+0

Gracias, esta es generalmente una buena idea. Pero no ayuda con la decisión de usar el entorno o la línea de comando. La elaboración de las entradas de configuración de su Ad.2. No encajará, por ejemplo, en los argumentos de línea de comando sería útil. ¿Qué no cabe en una cuerda? Si no encaja, probablemente debería pasarse indirectamente en una especie de archivo, ¿no es así? –

+0

Mi punto es: no obligue al usuario a usar los parámetros de línea de comando ** o ** variables de entorno. Sea flexible (y aún así preserve el código de mantenimiento). Creo que el archivo de configuración es el mejor lugar para almacenar la configuración (puede ser arbitrariamente largo, contener comentarios, etc.), sin embargo, a veces es útil anular la configuración del archivo usando parámetros de línea de comando. ¿Qué no encajará en los parámetros de línea de comando? Si necesita pasar varias rutas de archivos, probablemente funcione, pero a nadie le gustan las líneas de comando excesivamente largas. –

+0

El archivo de configuración es el mejor para los argumentos: esta es una opinión valiosa y el soporte para los comentarios es una buena razón para usarlo, gracias. Si usa variables de entorno al iniciar una aplicación desde un script por lotes, puede tener un formulario muy legible usando ['rem'] (http://technet.microsoft.com/en-us/library/bb490986.aspx) y [ 'set'] (http://technet.microsoft.com/en-us/library/bb490998.aspx). Si está generando un proceso, simplemente 'setenv' lo que desea antes de' spawnl'-ing. Es conveniente, legible y flexible. ¿Por qué usarías .config en lugar del entorno? _ Esa es la pregunta._ –

Cuestiones relacionadas