¿Por qué no exportar variables en la misma línea que las asigna?

44

De Cuál es el último argumento de la orden anterior?

shellcheck le dice que no exporte variables en la misma línea que las asigna.

Me preguntaba por qué?

¿Se aplica el mismo consejo a alias, declare, export, local, readonly, y typeset?

Tim
fuente
1
¿
Stéphane Chazelas
99
La regla de shellcheck en cuestión es SC2155. Hay bastante buena documentación en el wiki de shellcheck .
phunehehe
3
Además, algunos proyectiles más antiguos no aceptarían exporty asignarían juntos. El Bourne Shell de la herencia , por ejemplo, da salida a una "foo = 2 no es un identificador" error.
Dennis Williamson

Respuestas:

54

El problema es que en Bash cada comando tiene un solo código de salida. Cuando export foo="$(false)"el código de salida de falsesimplemente se descarta. Si en cambio lo haces

foo="$(false)"
export foo

se puede actuar sobre el primer comando que falla, por ejemplo, mediante la errexitconfiguración.

Declarar y asignar un literal de cadena como export foo='bar', por supuesto, no sufre este problema. Pero el cambio es la única constante en el desarrollo de software, y es simplemente un buen mantenimiento de las declaraciones a prueba de futuro dividiéndolos.

Además de los comandos específicos de la asignación que menciona, también hay varios comandos en una sola asignación, como foo="$(false)$(true)". Ver pipefailen man bashpara otro tal trampa.

Otra cosa para recordar es que la secuencia de declaración y asignación a veces es relevante. Por ejemplo, querrá declarar variables antes de asignarlas. (Desafortunadamente no es posible declarar variables antes de asignarlas por primera vez).local readonly

l0b0
fuente
Entonces, si uno está configurando una variable a partir de un literal, y no hay un código de salida para descartar, no hay nada de malo en hacerlo todo en una línea.
Monty Harder
1
En lo que respecta a este error de shellcheck, no. Pero como las respuestas ahora eliminadas estaban a mitad de camino entre ellas, el shell Bourne no admitió la sintaxis de asignación export, por lo que durante algunos años se recibió la sabiduría de hacerlo si era probable que el intérprete de uno fuera el shell Bourne.
JdeBP
@JdeBP, tenga en cuenta que el shell Bourne era compatible foo=$(cmd) export foo, aunque con la misma advertencia que cmdel estado de salida se pierde (pero hizo que el shell salga si falla set -e).
Stéphane Chazelas
Eso fue cubierto por mi primera oración.
JdeBP