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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10856129/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 22:10:44  来源:igfitidea点击:

Setting an environment variable before a command in Bash is not working for the second command in a pipe

bashenvironment-variables

提问by MartyMacGyver

In a given shell, normally I'd set a variable or variables and then run a command. Recently I learned about the concept of prepending a variable definition to a command:

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

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 notits arguments, for example, '[a-z]' 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 (for example, '[a-z]').

我也可以在 somecommand2 前面加上“FOO=bar”,这很有效,但会增加不必要的重复,并且对根据变量解释的参数(例如,“[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


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. The method of using redirection rather than a pipe is interesting as well.

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

采纳答案by Paused until further notice.

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

回答by 0xC0000022L

How about exporting the variable, but only inside the subshell?:

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

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

Keith has a point, to unconditionally execute the commands, do this:

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

(export FOO=bar; somecommand someargs | somecommand2)

回答by gniourf_gniourf

You can also use eval:

您还可以使用eval

FOO=bar eval 'somecommand someargs | somecommand2'


Since this answer with evaldoesn't seem to please everyone, let me clarify something: when used as written, with the single quotes, it is perfectly safe. 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).

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

As we get a few regular views, it's probably good to give an alternative to evalthat will please everyone, and has all the benefits (and perhaps even more!) of this quick eval“trick”. Just use a function! Define a function with all your commands:

当我们获得一些常规视图时,最好提供一个替代方案,以eval取悦所有人,并且具有这个快速eval“技巧”的所有好处(甚至更多!)。只用一个函数!使用所有命令定义一个函数:

mypipe() {
    somecommand someargs | somecommand2
}

and execute it with your environment variables like this:

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

FOO=bar mypipe

回答by benjimin

Use env.

使用env.

For example, env FOO=BAR command. Note that the environment variables will be restored/unchanged again when commandfinishes executing.

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

Just be careful about about shell substitution happening, i.e. if you want to reference $FOOexplicitly on the same command line, you may need to escape it so that your shell interpreter doesn't perform the substitution beforeit runs env.

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

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

回答by Spencer Rathbun

Use a shell script:

使用 shell 脚本:

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

> ./myscript