Corregir mayúsculas y minúsculas en la secuencia de comandos Bash y shell

193

Me encuentro con muchos scripts de shell con variables en mayúsculas, y siempre he pensado que hay un malentendido grave con eso. Tengo entendido que, por convención (y quizás por necesidad hace mucho tiempo), las variables de entorno están en mayúsculas.

Pero en entornos de scripting modernos como Bash, siempre he preferido la convención de nombres en minúsculas para variables temporales y mayúsculas solo para variables exportadas (es decir, de entorno) . Por ejemplo:

#!/usr/bin/env bash
year=`date +%Y`
echo "It is $year."
export JAVA_HOME="$HOME/java"

Esa siempre ha sido mi opinión sobre las cosas. ¿Existen fuentes autorizadas que estén de acuerdo o en desacuerdo con este enfoque, o es puramente una cuestión de estilo?

JasonSmith
fuente

Respuestas:

262

Por convención, las variables de entorno ( PAGER, EDITOR, ...) y las variables de shell internos ( SHELL,BASH_VERSION , ...) se capitalizan. Todos los demás nombres de variables deben estar en minúsculas.

Recuerde que los nombres de las variables distinguen entre mayúsculas y minúsculas; Esta convención evita anular accidentalmente variables ambientales e internas.

De acuerdo con esta convención, puede estar seguro de que no necesita conocer todas las variables de entorno utilizadas por las herramientas o shells de UNIX para evitar sobrescribirlas. Si es su variable, en minúscula. Si lo exportas, en mayúscula.

lhunath
fuente
8
+1. Buen punto sobre la sobreescritura accidental. Olvidé mencionarlo, pero ahora que lo mencionas, creo que decidí usar minúsculas porque leí o escuché sobre ese problema.
JasonSmith
55
Pensé que la razón principal para usar nombres de variables en mayúscula era evitar conflictos con los comandos de shell. Recientemente tuvimos el nombre de host de uno de nuestros servidores cambiado accidentalmente a '=' porque un script usaba una variable 'hostname'.
ThisSuitIsBlackNot
25
@ThisSuitIsBlackNot Ignorando el código basura, las variables tienen el prefijo de un dólar cuando se expanden y se usan en un lugar donde no se pueden confundir con un nombre de comando cuando no lo están. Obviamente, hacer hostname = moo te meterá en problemas. No porque esté usando un "nombre de host" en minúsculas, sino porque no está usando la sintaxis de asignación correcta. La asignación se realiza con hostname = moo, sin espacios. Suponiendo que el código es correcto, no necesita preocuparse por los nombres de variables que entran en conflicto con los nombres de los comandos.
Lunh
3
Todos los libros de texto que he visto siempre usan mayúsculas para todas las variables de shell. Mientras que los nombres de variables en minúsculas son permisibles, mayúsculas es la convención.
Brian S. Wilson el
3
No sabía esto, y solo perdí un par de horas. sobre usar USER="username"en un script bash automatizando algunos comandos remotos sobre ssh en lugar de user="username". Ugh! Me alegro de saber ahora!
Gabriel Staples
28

Cualquier convención de nomenclatura seguida de manera consistente siempre será de ayuda. Aquí hay algunos consejos útiles para nombrar variables de shell:

  • Utilice todas las mayúsculas y minúsculas para las variables y constantes exportadas, especialmente cuando se comparten entre múltiples scripts o procesos. Use un prefijo común siempre que sea aplicable para que las variables relacionadas se destaquen y no entren en conflicto con las variables internas de Bash, que son todas mayúsculas.

    Ejemplos:

    • Variables exportadas con un prefijo común: JOB_HOME JOB_LOG JOB_TEMP JOB_RUN_CONTROL
    • Constantes: LOG_DEBUG LOG_INFO LOG_ERROR STATUS_OK STATUS_ERROR STATUS_WARNING
  • Utilice el "caso de serpiente" ( todo en minúsculas y guiones bajos ) para todas las variables que están en un solo script o bloque.

    Ejemplos: input_file first_value max_amount num_errors

    Use mayúsculas y minúsculas cuando la variable local tenga alguna relación con una variable de entorno, como: old_IFS old_HOME

  • Use un guión bajo para las variables y funciones "privadas". Esto es especialmente relevante si alguna vez escribe una biblioteca de shell donde las funciones dentro de un archivo de biblioteca o entre archivos necesitan compartir variables, sin entrar en conflicto con nada que pueda tener un nombre similar en el código principal.

    Ejemplos: _debug _debug_level _current_log_file

  • Evitar caso del camello . Esto minimizará los errores causados ​​por errores tipográficos. Recuerde, las variables de shell son sensibles a mayúsculas y minúsculas .

    Ejemplos: inputArray thisLooksBAD , numRecordsProcessed,veryInconsistent_style


Ver también:

codeforester
fuente
1
Esta es una convención, pero apenas es universalmente aceptada. La justificación contra el caso de los camellos no es del todo convincente. La recomendación de usar SHOUTING para las variables exportadas es ligeramente controvertida.
tripleee
3
No afirmé que se trata de una convención comúnmente seguida. He visto que la mayoría de los programadores no piensan seriamente en seguir convenciones fuertes en los scripts de shell y piensan en anotar mis pensamientos en función de lo que he estado haciendo.
codeforester
8

Si las variables de shell se exportarán al entorno, vale la pena considerar que la definición de variable de entorno POSIX (edición 7, edición 2018) especifica:

Los nombres de las variables de entorno utilizados por las utilidades en el volumen Shell y Utilidades de POSIX.1-2017 consisten únicamente en letras mayúsculas, dígitos y el guión bajo ( _) de los caracteres definidos en el Conjunto de caracteres portátil y no comienzan con un dígito.

...

El espacio de nombres de las variables de entorno que contienen letras minúsculas está reservado para las aplicaciones. Las aplicaciones pueden definir cualquier variable de entorno con nombres de este espacio de nombres sin modificar el comportamiento de las utilidades estándar.

Anthony Geoghegan
fuente
6

Yo hago lo que tu haces Dudo que haya una fuente autorizada, pero parece un estándar de facto bastante extendido.

Draemon
fuente
1
Estoy de acuerdo. Es porque ALL_CAPS es feo, pero es bueno hacer que las VARIABLES AMBIENTALES se destaquen por ser feo.
delgado
1
Estoy de acuerdo con usted en el estilo de codificación, pero definitivamente no estoy de acuerdo con que esté muy extendido. Los scripts de Shell son uno de esos idiomas paralelos que las personas aprenden de manera informal, por lo que siento que todos siempre dicen LOCATION =cat /tmp/location.txt
JasonSmith el
@jhs: ¡obviamente he tenido suerte con los scripts de shell con los que he tenido que trabajar!
Draemon el
44
"El espacio de nombres de las variables de entorno que contienen letras minúsculas está reservado para las aplicaciones". - POSIX IEEE Std 1003.1-2008 sección 8.1
tripleee
5

En realidad, el término "variables de entorno" parece ser de acuñación bastante reciente. Kernighan y Pike en su libro clásico "El entorno de programación de UNIX", publicado en 1984, solo hablan de "variables de shell". ¡Ni siquiera hay una entrada para "entorno" en el índice!


fuente
8
Creo que es una omisión del libro. getenv (), setenv () y ambient se introdujeron en UNIX versión 7 (1979). en.wikipedia.org/wiki/Version_7_Unix
Juliano
3
Ese libro busca notar que las variables en mayúscula tienen un significado especial.
ashawley
3

Es solo una convención muy extendida, dudo que haya una fuente "autorizada" para ello.

Alnitak
fuente
1

Tiendo a usar ALL_CAPS tanto para el entorno como para las variables globales. Por supuesto, en Bash no hay un alcance variable real, por lo que hay una buena parte de las variables utilizadas como globales (principalmente configuraciones y seguimiento de estado) y relativamente pocos 'locales' (contadores, iteradores, cadenas parcialmente construidas y temporales)

Javier
fuente
Sí, conceptualmente pienso en las variables no exportadas como locales, ya que Bash a menudo está bifurcando los procesos secundarios para hacer lo que sea que tenga la tarea de hacer.
JasonSmith