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

本文讨论在Bash中通过在命令前设置环境变量,但这种方式在管道中对后续命令无效的问题。特别是涉及到LC_*变量时,影响仅限于命令本身而不包括其参数。文章提出了多种解决方案,包括在子shell中导出变量、使用shell脚本、定义函数以及使用`env`命令。目标是找到一种方法在不使用“export”且保持单行命令的同时,确保环境变量的正确设置。
摘要由CSDN通过智能技术生成

本文翻译自: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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值