Establecer una variable de entorno antes de que un comando en bash no funcione para el segundo comando en una tubería

En un shell dado, normalmente establecía una variable o variables y luego ejecutaba un comando. Recientemente aprendí sobre el concepto de anteponer una definición variable a un comando:

FOO=bar somecommand someargs 

Esto funciona … más o menos. No funciona cuando está cambiando una variable LC_ * (que parece afectar el comando pero NO sus argumentos, por ejemplo, rangos de caracteres ‘[az]’) o cuando la salida de la tubería a otro comando así:

 FOO=bar somecommand someargs | somecommand2 # somecommand2 is unaware of FOO 

Puedo anteponer somecommand2 con “FOO = bar” también, que funciona pero que agrega duplicación no deseada, y no ayuda con los argumentos que se interpretan según la variable (por ejemplo, ‘[az]’)

Entonces, ¿cuál es una buena manera de hacer esto en una sola línea? Estoy pensando en algo del orden de:

 FOO=bar (somecommand someargs | somecommand2) # Doesn't actually work 

Editar: ¡obtuve muchas buenas respuestas! El objective es mantener esto como una línea, preferiblemente sin usar “exportar”. El método que utilizaba una llamada a bash era el mejor en general, aunque la versión entre paréntesis con “exportación” en ella era un poco más compacta. El método de usar la redirección en lugar de una tubería también es interesante.

 FOO=bar bash -c 'somecommand someargs | somecommand2' 

¿Qué hay de exportar la variable, pero solo dentro de la subshell ?:

 (export FOO=bar && somecommand someargs | somecommand2) 

Keith tiene un punto, para ejecutar incondicionalmente los comandos, haz esto:

 (export FOO=bar; somecommand someargs | somecommand2) 

También puedes usar eval :

 FOO=bar eval 'somecommand someargs | somecommand2' 

Dado que esta respuesta con eval no parece complacer a todos, déjenme aclarar algo: cuando se usa como está escrito, con las comillas simples , es perfectamente seguro. Es bueno, ya que no lanzará un proceso externo (como la respuesta aceptada) ni ejecutará los comandos en una subcamada extra (como la otra respuesta).

A medida que obtengamos algunos puntos de vista regulares, probablemente sea bueno ofrecer una alternativa de eval que satisfaga a todos, y que tenga todos los beneficios (¡y tal vez incluso más!) De este rápido “truco” de eval . Solo usa una función! Define una función con todos tus comandos:

 mypipe() { somecommand someargs | somecommand2 } 

y ejecútelo con sus variables de entorno como esta:

 FOO=bar mypipe 

¿Qué hay de usar un script de shell?

 #!/bin/bash # myscript FOO=bar somecommand someargs | somecommand2 > ./myscript