Définition d’une variable d’environnement avant une commande en bash ne fonctionnant pas pour la seconde commande dans un tube

Dans un shell donné, je définirais normalement une variable ou des variables, puis exécuterais une commande. Récemment, j’ai appris à append une définition de variable à une commande:

FOO=bar somecommand someargs 

Cela fonctionne … en quelque sorte. Cela ne fonctionne pas lorsque vous modifiez une variable LC_ * (qui semble affecter la commande mais PAS ses arguments, par exemple, les plages de caractères “[az]”) ou lorsque vous transmettez la sortie à une autre commande:

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

Je peux aussi append somecommand2 avec “FOO = bar”, qui fonctionne mais qui ajoute une duplication indésirable, et cela ne facilite pas les arguments interprétés en fonction de la variable (par exemple ‘[az]’)

Alors, comment faire cela sur une seule ligne? Je pense à quelque chose de l’ordre de:

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

Edit: J’ai eu beaucoup de bonnes réponses! Le but est de garder celui-ci un one-liner, de préférence sans “exporter”. La méthode utilisant un appel à bash était globalement la meilleure, bien que la version entre parenthèses avec “export” était un peu plus compacte. La méthode d’utilisation de la redirection plutôt que celle d’un tube est également intéressante.

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

Que diriez-vous d’exporter la variable, mais seulement à l’intérieur du sous-shell?:

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

Keith a un point, pour exécuter inconditionnellement les commandes, faites ceci:

 (export FOO=bar; somecommand someargs | somecommand2) 

Vous pouvez également utiliser eval :

 FOO=bar eval 'somecommand someargs | somecommand2' 

Comme cette réponse avec eval ne semble pas plaire à tout le monde, laissez-moi clarifier quelque chose: lorsqu’il est utilisé tel quel, avec les guillemets simples , il est parfaitement sûr. C’est bien car cela ne lancera pas de processus externe (comme la réponse acceptée) et n’exécutera pas les commandes dans un sous-shell supplémentaire (comme l’autre réponse).

Au fur et à mesure que nous obtenons quelques points de vue réguliers, il est probablement bon de proposer une alternative à eval qui plaira à tout le monde et qui présente tous les avantages (et peut-être même plus!) De cette «astuce» à eval rapide. Utilisez simplement une fonction! Définissez une fonction avec toutes vos commandes:

 mypipe() { somecommand someargs | somecommand2 } 

et l’exécuter avec vos variables d’environnement comme ceci:

 FOO=bar mypipe 

Que diriez-vous d’utiliser un script shell?

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