En un shell dado, normalmente establecería una variable o variables y luego ejecutaría 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, '[az]' rangos de caracteres) o cuando canaliza la salida a otro comando de esta manera:
FOO=bar somecommand someargs | somecommand2 # somecommand2 is unaware of FOO
También puedo anteponer somecommand2 con "FOO = bar", que funciona, pero que agrega duplicación no deseada, y no ayuda con argumentos que se interpretan dependiendo de 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
¡Tengo muchas buenas respuestas! El objetivo es mantener esto de una línea, preferiblemente sin usar "exportar". El método que utiliza una llamada a Bash fue el mejor en general, aunque la versión entre paréntesis con "exportar" era un poco más compacta. El método de utilizar la redirección en lugar de una tubería también es interesante.
fuente
(T=$(date) echo $T)
funcionaráRespuestas:
fuente
somecommand
como sudo, debe pasar sudo a la-E
bandera para pasar a través de las variables. Porque las variables pueden introducir vulnerabilidades. stackoverflow.com/a/8633575/1695680FOO_X=foox bash -c 'echo $FOO_X'
funciona como se esperaba, pero con nombres var específicos falla:DYLD_X=foox bash -c 'echo $DYLD_X'
eco en blanco. ambos trabajan usando eneval
lugar debash -c
¿Qué tal exportar la variable, pero solo dentro de la subshell ?:
Keith tiene un punto, para ejecutar incondicionalmente los comandos, haga esto:
fuente
;
lugar de&&
; no hay forma deexport FOO=bar
que falle&&
ejecuta el comando izquierdo, luego ejecuta el comando derecho solo si el comando izquierdo tuvo éxito.;
ejecuta ambos comandos incondicionalmente. Elcmd.exe
equivalente de Windows por lotes ( ) de;
es&
.(FOO=XXX ; echo FOO=$FOO) ; echo FOO=$FOO
rendimientosFOO=XXX\nFOO=\n
.source
(aka.
) en ese caso? Además, los backticks ya no deberían usarse en estos días y esta es una de las razones por las cuales, el uso$(command)
es muuuucho más seguro.bash
pero podría ser otra cosa, por ejemplodash
) y no tengo ningún problema si debo usar comillas dentro del comando args (someargs
).También puedes usar
eval
:Como esta respuesta
eval
no parece complacer a todos, permítanme aclarar algo: cuando se usa tal como está escrita, con comillas simples , es perfectamente segura. Es bueno, ya que no iniciará un proceso externo (como la respuesta aceptada) ni ejecutará los comandos en una subshell adicional (como la otra respuesta).A medida que obtenemos algunas vistas regulares, probablemente sea bueno dar una alternativa
eval
que complazca a todos y que tenga todos los beneficios (¡y quizás incluso más!) De este rápidoeval
"truco". ¡Solo usa una función! Defina una función con todos sus comandos:y ejecútelo con sus variables de entorno como esta:
fuente
eval
.eval
es malvado sin entender de qué se trata el maleval
. Y tal vez no estás realmente entendiendo esta respuesta después de todo (y realmente no tiene nada de malo). En el mismo nivel: ¿diría quels
es malo porquefor file in $(ls)
es malo? (y sí, no rechazó la respuesta aceptada y tampoco dejó un comentario). SO es un lugar tan extraño y absurdo a veces.eval
eval
suenas como un chico que una vez leyó que es malvado sin entender de qué se trata , me refiero a tu oración: esta respuesta carece de todas las advertencias y explicaciones necesarias al hablareval
.eval
no es malo ni peligroso; no másbash -c
.eval
. En la respuesta, siempre que los argumentos se hayan citado solo para protegerlos de la expansión variable, por lo que no veo ningún problema con la respuesta.eval
es un problema de seguridad en general (comobash -c
pero menos obvio), por lo que los peligros deben mencionarse en una respuesta que proponga su uso. Los usuarios descuidados pueden tomar la respuesta (FOO=bar eval …
) y aplicarla a su situación para generar problemas. Pero obviamente era más importante para el que respondía averiguar si rechacé su respuesta y / u otras respuestas que mejorar algo. Como escribí antes, la justicia no debería ser la principal preocupación; no ser peor que cualquier otra respuesta dada también es irrelevante.Uso
env
.Por ejemplo,
env FOO=BAR command
. Tenga en cuenta que las variables de entorno se restaurarán / modificarán nuevamente cuandocommand
finalice la ejecución.Solo tenga cuidado con la sustitución de shell, es decir, si desea hacer referencia
$FOO
explícitamente en la misma línea de comando, es posible que deba escapar para que su intérprete de shell no realice la sustitución antes de que se ejecuteenv
.fuente
Use un script de shell:
fuente
export
; de lo contrario$FOO
será una variable de shell, no una variable de entorno, y por lo tanto no será visible parasomecommand
osomecommand2
.