在bash中的命令之前設置環境變量不適用於管道中的第二個命令

本文翻譯自: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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章