Donde es “exportar var = valor” no está disponible?

31

He recogido, probablemente en Usenet a mediados de la década de 1990 (!), Que el constructo

export var=value

es un Bashismo, y que la expresión portátil es

var=value
export var

He estado abogando por esto durante años, pero recientemente, alguien me desafió al respecto, y realmente no puedo encontrar ninguna documentación que respalde lo que solía ser una creencia sólida mía.

Buscar en Google "export: command not found"no parece mostrar ningún caso en el que alguien haya tenido este problema, por lo que incluso si es genuino, supongo que no es muy común.

(Los éxitos que consigo parecen ser novatos que copiar / pegar puntuacion, y terminó con 'export: command not foundo algunos de tales, o está tratando de utilizar exportcon sudoy novatos csh. Usuarios que intentan utilizar la sintaxis Bourne shell)

Ciertamente, puedo decir que funciona en OS X y en varias distribuciones de Linux, incluidas las que shestán dash.

sh$ export var=value
sh$ echo "$var"
value
sh$ sh -c 'echo "$var"'  # see that it really is exported
value

En el mundo de hoy, ¿es seguro decir que export var=valuees seguro de usar?

Me gustaría entender cuáles son las consecuencias. Si no es portátil para v7 "Bourne classic", eso es apenas más que trivialidades. Si hay sistemas de producción donde el shell realmente no puede hacer frente a esta sintaxis, sería útil saberlo.

tripleee
fuente
2
gracias Finalmente entendí por qué veo tan a menudo lo que pensé que era inútil: var = value; export var
Thorsten Staerk
2
Todavía hay algunas cajas de Solaris dando vueltas, y esas son notoriamente frugales en sus herramientas estándar; en el otro extremo del espectro, ¿no busyboxviene con su propio caparazón mínimo? (No estoy en condiciones de intentarlo en este momento).
Ulrich Schwarz
Gracias Ulrich, Solaris puede ser el culpable de por qué esta larga sintaxis todavía existe.
Thorsten Staerk

Respuestas:

20
export foo=bar

no era compatible con el shell Bourne (un antiguo shell de los años 70 del que shderivan implementaciones modernas como ash / bash / ksh / yash / zsh). Eso fue introducido por ksh.

En el shell Bourne, harías:

foo=bar export foo

o:

foo=bar; export foo

o con set -k:

export foo foo=bar

Ahora, el comportamiento de:

export foo=bar

varía de caparazón a caparazón.

El problema es que las asignaciones y los argumentos de comandos simples se analizan e interpretan de manera diferente.

El foo=baranterior es interpretado por algunas conchas como un argumento de mando y por otros como una asignación (a veces).

Por ejemplo,

a='b c'
export d=$a

se interpreta como:

'export' 'd=b' 'c'

con algunos shells ( ashversiones anteriores de zsh(en emulación sh), yash) y:

'export' 'd=b c'

en los otros ( bash, ksh).

Mientras

export \d=$a

o

var=d
export $var=$a

se interpretaría de la misma manera en todos los shells (as 'export' 'd=b' 'c') porque esa barra invertida o signo de dólar detiene los shells que lo admiten para considerar esos argumentos como asignaciones.

Si exportse cita a sí mismo o es el resultado de alguna expansión (incluso en parte), dependiendo del caparazón, también dejaría de recibir el tratamiento especial.

Consulte " ¿Se necesitan comillas para la asignación de variables locales? " Para obtener más detalles al respecto.

Sin embargo, la sintaxis de Bourne:

d=$a; export d

todos los shells interpretan lo mismo sin ambigüedad ( d=$a export dtambién funcionaría en el shell Bourne y los shells compatibles con POSIX, pero no en versiones recientes de, a zshmenos que sea en shemulación).

Puede ser mucho peor que eso. Vea, por ejemplo, esa discusión reciente sobrebash cuándo están involucradas las matrices.

(OMI, fue un error introducir esa función ).

Stéphane Chazelas
fuente
Me sorprendió que no se requiera el punto y coma foo=bar export foo, ya que siempre lo había visto allí. Sé que la exportación es una función integrada, pero ¿por qué se foo=bar; foo=baz export foo; echo $foocomporta de manera diferente foo=bar; foo=baz /bin/cat /dev/null; echo $foo?
jrw32982 es compatible con Monica el
3
@ jrw32982, porque está integrado. Todavía lo obtienes en los proyectiles POSIX modernos, pero solo para construcciones especiales que exportson.
Stéphane Chazelas 01 de
Aunque no se discute declare, exportrecomiendo que cualquiera que se preocupe por la seguridad lea la discusión en el enlace que StéphaneChazelas proporcionó a bash.bugs .
John1024
¡Gran respuesta! Pero tardó mucho tiempo en llegar, d=$a export des interpretado de la misma manera por todos los proyectiles sin ambigüedad ;-)
conny
@conny, d=$a export dya no funciona zsh, así que actualicé la respuesta. Ver editar.
Stéphane Chazelas
28

No es un bashism sino una sintaxis compatible con POSIX. En realidad, comenzó como un kshismo hace mucho tiempo y más tarde fue adoptado por casi todos los shells basados ​​en sintaxis Bourne. La única excepción notoria es /bin/shSolaris 10 y versiones anteriores que se adhieren a la sintaxis de shell Bourne heredada. Con suerte, Solaris 11 utiliza un shell compatible con POSIX como /bin/sh.

Por cierto, exportya era un comando incorporado en el shell Bourne heredado, por lo que buscar en Google export: command not foundfue engañoso.

Aquí está el comportamiento de shell Bourne heredado cuando exportse combina con una afectación:

$ export var=22
var=22: is not an identifier

Para los nostálgicos, el código fuente de este shell Bourne original está disponible y puede compilarse para la mayoría de las distribuciones de Unix y Linux.

jlliagre
fuente
¡Muchas gracias por el conocimiento histórico y el mensaje de error correcto para google! Obvio en retrospectiva, sonrojo ...
tripleee
44
Ese no es el código fuente del shell Bourne original, es un sh OpenSolaris modificado. Es el caparazón de Bourne, pero después de haber sufrido décadas de evolución. El shell Bourne original, tal como se envía con Unix V7, se puede encontrar en la Unix Heritage Society
Stéphane Chazelas
1
@ StéphaneChazelas Hablando estrictamente, usted es, como siempre, correcto. Sin embargo, tenga en cuenta que no escribí "el shell Bourne original" sino "este shell Bourne original", ya que me refería al shell utilizado por Solaris 10 y su código fuente que puede compilarse en plataformas modernas. Tenga en cuenta también que el shell Bourne tuvo varias características agregadas entre 1977 y 1989, pero luego esencialmente dejó de evolucionar (portación externa / adaptación a plataformas más nuevas y correcciones de errores) en los últimos 25 años más o menos.
jlliagre