本文翻译自:Setting an environment variable before a command in bash not working for second command in a pipe
In a given shell, normally I'd set a variable or variables and then run a command. 在给定的shell中,通常我会设置一个或多个变量,然后运行一个命令。 Recently I learned about the concept of prepending a variable definition to a command: 最近我了解了将变量定义添加到命令的概念:
FOO=bar somecommand someargs
This works... kind of. 这工作......有点儿。 It doesn't work when you're changing a LC_* variable (which seems to affect the command but NOT its arguments, eg, '[az]' char ranges) or when piping output to another command thusly: 当你改变一个LC_ *变量(它似乎影响命令而不是它的参数,例如'[az]'字符范围)或者输出到另一个命令时,它不起作用:
FOO=bar somecommand someargs | somecommand2 # somecommand2 is unaware of FOO
I can prepend somecommand2 with "FOO=bar" as well, which works but which adds unwanted duplication, and it doesn't help with arguments that are interpreted depending on the variable (eg '[az]') 我可以在“FOO = bar”之前添加somecommand2,但是它可以添加不需要的重复,但它对根据变量解释的参数没有帮助(例如'[az]')
So, what's a good way to do this on a single line? 那么,在一条线上做这件事的好方法是什么? I'm thinking something on the order of: 我正在考虑以下顺序:
FOO=bar (somecommand someargs | somecommand2) # Doesn't actually work
Edit: I got lots of good answers! 编辑:我有很多好的答案! The goal is to keep this a one-liner, preferably without using "export". 目标是保持一个单行,最好不使用“导出”。 The method using a call to bash was best overall, though the parenthetical version with "export" in it was a little more compact. 使用bash调用的方法总体上是最好的,尽管带有“export”的括号版本更紧凑。 The method of using redirection rather than a pipe is interesting as well. 使用重定向而不是管道的方法也很有趣。
#1楼
参考:https://stackoom.com/question/jYAr/在bash中的命令之前设置环境变量不适用于管道中的第二个命令
#2楼
How about exporting the variable, but only inside the subshell?: 如何导出变量,但仅在子shell中?:
(export FOO=bar && somecommand someargs | somecommand2)
Keith has a point, to unconditionally execute the commands, do this: Keith有一个观点,无条件执行命令,执行此操作:
(export FOO=bar; somecommand someargs | somecommand2)
#3楼
FOO=bar bash -c 'somecommand someargs | somecommand2'
#4楼
How about using a shell script? 如何使用shell脚本?
#!/bin/bash
# myscript
FOO=bar
somecommand someargs | somecommand2
> ./myscript
#5楼
You can also use eval
: 你也可以使用eval
:
FOO=bar eval 'somecommand someargs | somecommand2'
Since this answer with eval
doesn't seem to please everyone, let me clarify something: when used as written, with the single quotes , it is perfectly safe. 由于这个带有eval
答案似乎并不能让所有人满意,所以让我澄清一下:当使用单引号书写时,它是完全安全的。 It is good as it will not launch an external process (like the accepted answer) nor will it execute the commands in an extra subshell (like the other answer). 它很好,因为它不会启动外部进程(如接受的答案),也不会在额外的子shell中执行命令(如另一个答案)。
As we get a few regular views, it's probably good to give an alternative to eval
that will please everyone, and has all the benefits (and perhaps even more!) of this quick eval
“trick”. 当我们获得一些常规视图时,给予每个人eval
替代方案可能是好的,并且具有这种快速eval
“技巧”的所有好处(甚至可能更多!)。 Just use a function! 只需使用一个功能! Define a function with all your commands: 使用所有命令定义函数:
mypipe() {
somecommand someargs | somecommand2
}
and execute it with your environment variables like this: 并使用您的环境变量执行它,如下所示:
FOO=bar mypipe
#6楼
Use env
. 使用env
。
For example, env FOO=BAR command
. 例如, env FOO=BAR command
。 Note that the environment variables will be restored/unchanged again when command
finishes executing. 请注意,当command
完成执行时,环境变量将再次恢复/未更改。
Just be careful about about shell substitution happening, ie if you want to reference $FOO
explicitly on the same command line, you may need to escape it so that your shell interpreter doesn't perform the substitution before it runs env
. 关于shell替换发生时要小心,即如果你想在同一命令行上显式引用$FOO
,你可能需要转义它,以便你的shell解释器在运行env
之前不执行替换。
$ export FOO=BAR
$ env FOO=FUBAR bash -c 'echo $FOO'
FUBAR
$ echo $FOO
BAR