在bash中的命令之前设置环境变量不适用于管道中的第二个命令

时间:2012-06-01 19:17:21

标签: bash environment-variables

在给定的shell中,通常我会设置一个或多个变量,然后运行一个命令。最近我了解了将变量定义添加到命令的概念:

FOO=bar somecommand someargs

这有效......有点儿。当你改变一个LC_ *变量(它似乎影响命令而不是它的参数,例如'[a-z]'字符范围)或者输出到另一个命令时,它不起作用:

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

我也可以将somecommand2添加到“FOO = bar”中,这可以起作用但会增加不需要的重复,并且它对根据变量解释的参数没有帮助(例如'[az]')

那么,在一条线上做这件事的好方法是什么?我正按照以下顺序思考:

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

编辑:我得到了很多好的答案!目标是保持一个单行,最好不使用“导出”。使用bash调用的方法总体上是最好的,尽管带有“export”的括号版本更紧凑。使用重定向而不是管道的方法也很有趣。

6 个答案:

答案 0 :(得分:263)

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

答案 1 :(得分:181)

如何导出变量,但仅在子shell中?:

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

Keith有一个观点,无条件地执行命令,执行此操作:

(export FOO=bar; somecommand someargs | somecommand2)

答案 2 :(得分:38)

您还可以使用eval

FOO=bar eval 'somecommand someargs | somecommand2'

由于eval的答案似乎并不能让所有人满意,让我澄清一下:当使用单引号作为书面文字使用时,它非常安全。它很好,因为它不会启动外部进程(如接受的答案),也不会在额外的子shell中执行命令(如其他答案)。

正如我们得到一些常规观点一样,为eval提供一个可以取悦所有人的替代方案可能会很好,并且拥有这个快速eval“的所有好处(甚至可能更多!)特技”。只需使用一个功能!使用所有命令定义函数:

mypipe() {
    somecommand someargs | somecommand2
}

并使用您的环境变量执行它:

FOO=bar mypipe

答案 3 :(得分:3)

一种简单的方法是利用;

例如:

ENV=prod; ansible-playbook -i inventories/$ENV --extra-vars "env=$ENV"  deauthorize_users.yml --check

答案 4 :(得分:2)

使用env

例如,env FOO=BAR command。请注意,command完成执行后,环境变量将再次恢复/不变。

请注意发生外壳替换的情况,即,如果要在同一命令行上显式引用$FOO,则可能需要对其进行转义,以便您的外壳解释器不执行替换 之前,它会运行env

$ export FOO=BAR
$ env FOO=FUBAR bash -c 'echo $FOO'
FUBAR
$ echo $FOO
BAR

答案 5 :(得分:-4)

如何使用shell脚本?

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

> ./myscript