Configuración de usuario de un script de Shell. ¿Mejores prácticas?

13

Estoy escribiendo un script de shell con algunas variables que el usuario debe configurar. Habrá un instalador para descargar y configurar el script, posiblemente haciendo una serie de preguntas. El script en cuestión está dirigido a otros desarrolladores.

Esto se puede implementar de varias maneras:

  1. Use marcadores de posición en el script en sí y úselos sedpara reemplazarlos durante la instalación (algo como esto: /programming/415677/how-to-replace-placeholders-in-a-text-file )

    • Pros: todas las definiciones de variables están contenidas en el script. Es fácil descargar el script manualmente y configurar las variables para los usuarios que prefieren un editor sobre el instalador.

    • Contras: es difícil reconfigurar las variables a través del instalador una vez que están en su lugar. A menos que cree una expresión regular más compleja que sea propensa a errores.

  2. Use un archivo de configuración , básicamente otro script de shell con asignaciones, y use sourcepara incluirlo. (¿Y probablemente colocarlo ~/.scriptname? El script principal se copia a /usr/local/bin)

    • Pros: es fácil volver a configurar el guión. Incluso podría agregar un parámetro para hacerlo desde el script principal (probablemente también funcionaría en la primera solución, pero editar un script desde sí mismo no parece una muy buena idea)

    • Contras: el script ahora depende de dos archivos y el usuario debe ejecutar el instalador para que se cree el archivo de configuración. Esto se puede resolver generando automáticamente un archivo de configuración si no existe ninguno. Pero localizar un archivo de configuración externo seguirá siendo más engorroso para los usuarios que solo desean descargar el script, editarlo y terminar con él.

Además, algunas opciones sobre cómo el usuario debe administrar la configuración después de la instalación:

  1. Git como
    $ myscript config server.host example.org $ myscript config server.proxypath / home / johndoe / proxy $ myscript config server.httppath / home / johndoe / web


  2. Configuración interactiva de $ myscript
    Ingrese el nombre de host del servidor: example.org
    Ingrese la ruta al proxy en el servidor: / home / johndoe / proxy
    Ingrese la ruta al directorio http en el servidor: / home / johndoe / web

  3. getopts con opciones largas
    $ myscript --host example.org --proxypath / home / johndoe / proxy --httppath / home / johndoe / web


  4. Configuración simple de $ myscript example.org / home / johndoe / proxy / home / johndoe / web

¿Hay alguna otra forma de hacer esto que considerarías?
¿Alguna mejor práctica, algo elegante?

Charlie Rudenstål
fuente
2
No dudo que tu pueda escribir un script de shell que haga todo esto, pero la pregunta es por qué desea escribir algo tan complejo como requiere un instalador en un script de shell. De todos modos, mire cómo el sistema de configuración del kernel de Linux administra su archivo de configuración.
Bien. El script 'instalador' solo descargará el script real, lo copiará en su ubicación correcta y hará una serie de preguntas para la configuración (3-4 variables). De esta manera puedo dar a los usuarios una sola línea de comando, olvidando el script de instalación y canalizándolo a / bin / sh. Por supuesto, podría omitir el instalador y simplemente agregar un parámetro 'instalar' al script principal. Tal vez una mejor solución, ¿qué te parece?
Charlie Rudenstål
"pero la pregunta es por qué quieres escribir algo tan complejo". Aquí está el script en cuestión: github.com/charlie-rudenstal/depo Estoy tratando de reducir la cantidad de pasos que los nuevos usuarios deben realizar, especialmente durante el instalación. Buscando hacer que la configuración del servidor requerida también sea automática
Charlie Rudenstål

Respuestas:

6

¿Qué esperaría de un programa cuerdo (un script de shell o no):

  • Yo nunca tengo que alterar el ejecutable para simplemente configurarlo. Este no es un núcleo del sistema operativo.
  • Puedo pasar cualquier configuración usando la línea de comando. Esto es imprescindible para cada información que no tenga un incumplimiento razonable. La única excepción es una contraseña que necesita una entrada interactiva.
  • Opcionalmente, puedo pasar una configuración usando una variable de entorno.
  • Puedo escribir la configuración en un archivo de configuración, y este archivo se usará si está presente con un nombre conocido o si se señala explícitamente el uso de los dos métodos anteriores.
  • El archivo de configuración utiliza los mismos nombres de configuración y sintaxis que la línea de comando.
9000
fuente
Buen consejo. ¿Sería esta su orden preferida? (1) Verifique la configuración pasada en la línea de comando (2) Verifique la configuración en un .scriptnameConfig en el mismo directorio (3) Verifique la configuración en una variable de entorno (4) Verifique la configuración en un .scriptnameConfig en ~ / .scriptnameConfig (5) Use el valor predeterminado configuración
Charlie Rudenstål
"El archivo de configuración utiliza los mismos nombres de configuración y sintaxis que la línea de comandos". - ¿Cómo se supone que debe verse? Iba a usar la sintaxis de asignación para los scripts de shell normales: SETTING = VALUE. ¿No se sentiría un poco extraño el comando como que la sintaxis se siente dentro de un archivo de configuración?
Charlie Rudenstål
Vea cómo mounto le sshpermite usar la misma sintaxis en la línea de comando y en la configuración. No necesita copiar totalmente la sintaxis de la línea de comandos; en lugar de '--foo = bar' puedes usar 'foo = bar'. Si usó 'BarOption: Foo' en su lugar, sería mucho menos conveniente: la necesidad de recordar si el caso es significativo, qué palabra clave se acepta en el archivo y cuál en la línea de comando, y la imposibilidad de copiar y pegar un comando de trabajo línea en un archivo de configuración con solo edición cosmética.
9000
3

Cuando necesito escribir una secuencia de comandos elaborada con varias opciones de configuración, uso Python con el argumento y bibliotecas ConfigParser . Esos ayudan con la implementación, pero el proceso se aplica a cualquier script de shell:

  1. Busca un archivo de configuración. Si existe, lea cualquier configuración que tenga en una tabla de búsqueda / diccionario.
  2. Analiza los argumentos de la línea de comandos con nombre. Para cada argumento proporcionado, anule el valor cargado desde el archivo de configuración si existe. Para cualquier argumento que no se pase en la línea de comando y no en la configuración, use un valor predeterminado.
  3. Ejecuta la función principal del script
  4. Si el archivo de configuración no existe, escriba los valores pasados ​​y / o predeterminados.

Mi preferencia es que un archivo de configuración contenga las opciones preferidas cuando el script se vaya a usar repetidamente, pero deje que se anule cualquier argumento de la línea de comandos. Escriba el archivo de configuración utilizando esos parámetros la primera vez que se ejecute. El archivo de configuración se puede compartir y confirmar en un repositorio de código.

En mi caso más reciente, también escribí los valores predeterminados de la [DEFAULT]sección en la parte superior del archivo de configuración, luego tenía una sección para cada "entorno" con anulaciones apropiadas para cada uno. El "entorno" es el primer parámetro sin nombre del script. Entonces, en este caso, los parámetros se eligen como valores predeterminados integrados -> valor predeterminado del archivo de configuración -> valor de la sección del archivo de configuración -> parámetro de línea de comandos . Un parámetro de línea de comando adicional ofrece la opción de sobrescribir la configuración existente con el valor de la última ejecución. Este archivo de configuración se escribe en el directorio actual, por lo que se aplica por proyecto y se puede confirmar con el resto del código. Cualquier otra persona que esté revisando el mismo proyecto comenzará con la misma configuración.

Matt S
fuente
"Un parámetro de línea de comando adicional ofrece la opción de sobrescribir la configuración existente con el valor de la última ejecución". Este es un enfoque interesante. Una forma práctica de combinar parámetros con la configuración.
Charlie Rudenstål
+1, también recomendaría establecer valores predeterminados en un default.configarchivo ubicado en el mismo directorio que el script, luego buscar un archivo de configuración en ~/.scriptnamepara anular estos valores. De esa manera, cada valor tiene un valor predeterminado válido y es más fácil de mantener.
Aaron
2

La edición de marcadores de posición es propensa a errores.

Me gustaría usar un archivo de configuración.

Su preocupación por la dependencia es válida, sin embargo, no recuerdo haber usado demasiadas herramientas compuestas de un solo archivo. Entonces teóricamente tienes razón, pero prácticamente debería estar bastante bien.

Una tercera opción es hacer que el software de configuración escriba una nueva versión personalizada que sea específica para las opciones y parámetros seleccionados. Esto puede ser más difícil de escribir y probar, por supuesto :)

Ninguna posibilidad
fuente