452

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

FOO=bar somecommand someargs

这行得通……有点。当您更改 LC_* 变量(这似乎会影响命令,但影响其参数,例如 '[az]' 字符范围)或因此将输出管道传输到另一个命令时,它不起作用:

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

我也可以在 somecommand2 前面加上“FOO=bar”,这很有效,但会增加不必要的重复,而且它对根据变量解释的参数没有帮助(例如,'[az]')。

那么,在单行上执行此操作的好方法是什么?

我正在考虑以下顺序:

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

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

4

6 回答 6

408
FOO=bar bash -c 'somecommand someargs | somecommand2'
于 2012-06-01T19:39:08.603 回答
269

如何导出变量,但只在子外壳内?:

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

Keith 有一个观点,要无条件地执行命令,请执行以下操作:

(export FOO=bar; somecommand someargs | somecommand2)
于 2012-06-01T19:25:04.350 回答
57

您还可以使用eval

FOO=bar eval 'somecommand someargs | somecommand2'

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

当我们获得一些常规视图时,最好提供一个让每个人都满意的替代方案,并且拥有这个快速“技巧”eval的所有好处(甚至可能更多!) 。eval只需使用一个功能!使用所有命令定义一个函数:

mypipe() {
    somecommand someargs | somecommand2
}

并使用您的环境变量执行它,如下所示:

FOO=bar mypipe
于 2015-12-05T07:39:59.563 回答
36

使用env.

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

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

$ export FOO=BAR
$ env FOO=FUBAR bash -c 'echo $FOO'
FUBAR
$ echo $FOO
BAR
于 2019-06-26T04:19:30.973 回答
20

一个简单的方法是利用;

例如:

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

command1; command2在执行command1之后依次执行command2。命令是否成功并不重要。

于 2020-06-20T07:50:51.187 回答
-5

使用 shell 脚本:

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

> ./myscript
于 2012-06-01T19:40:13.293 回答