bash 在 shell 别名中设置环境变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33363345/
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-18 13:49:26  来源:igfitidea点击:

Set an environment variable within a shell alias

bashshellenvironment-variablesalias

提问by Fabian Tamp

On my system, I've got two versions of Java installed - some programs require Java 7, some require Java 8.

在我的系统上,我安装了两个版本的 Java - 有些程序需要 Java 7,有些需要 Java 8。

Java 8 is my system default, so when I've been running the Java 7 commands, I've been using:

Java 8 是我的系统默认值,所以当我运行 Java 7 命令时,我一直在使用:

JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.*.jdk/Contents/Home/ \
java_7_program

I want to set an alias so I can instead write

我想设置一个别名,这样我就可以写

j7 java_7_program

I've defined:

我已经定义:

alias j7='JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.*.jdk/Contents/Home/'

But then running j7 java -versionproduces:

但随后运行j7 java -version会产生:

java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

The man page(search for "Aliases") states that this is done as a direct substitution. Is there a reason as to why this isn't working?

手册页(搜索“别名”)指出,这是作为一个直接替代完成。有没有理由说明为什么这不起作用?

bash --versionprints GNU bash, version 4.3.42(1)-release (x86_64-apple-darwin14.5.0)

bash --version印刷 GNU bash, version 4.3.42(1)-release (x86_64-apple-darwin14.5.0)

A more isolated example (minus the java):

一个更孤立的例子(减去java):

$ alias foo='BAR=baz'
$ type foo
foo is aliased to `BAR=baz'
$ foo echo $BAR
[blank line]

采纳答案by gniourf_gniourf

Answering your isolated example:

回答您的孤立示例:

when you do something like this:

当你做这样的事情时:

bar=foo my_command

then baris set in my_command's environment (and is not seen by the current shell). Hence, when you do:

thenbar设置在my_command的环境中(当前shell 看不到)。因此,当您执行以下操作时:

bar=stuff
bar=foo my_command "$bar"

since the expansion of $baroccurs before my_commandis executed, then it's like doing:

由于扩展$bar发生在my_command执行之前,那么它就像做:

bar=foo my_command stuff

since the $baris expanded beforemy_command is forked. That explains the [blank line]you obtain in your example:

因为my_command 分叉之前$bar扩展了。这解释了您在示例中获得的内容:[blank line]

$ alias foo='BAR=baz'
$ type foo
foo is aliased to `BAR=baz'
$ foo echo $BAR
[blank line]


Just for fun, try these:

只是为了好玩,试试这些:

$ alias foo=BAR=baz
$ BAR=something
$ foo echo "$BAR"
something

makes sense?

说得通?

$ alias foo=BAR=baz
$ foo eval 'echo "$BAR"'
baz

this is because BARis passed in eval's environment, and then echo "$BAR"is expanded… with the expected value (note the single quotes!).

这是因为BAReval's 环境中传递,然后echo "$BAR"用预期的值扩展……(注意单引号!)。

Similarly,

相似地,

$ alias foo=BAR=baz
$ foo sh -c 'echo "$BAR"'
baz

回答by Richard

The jdk1.7.*.jdkbit is probably the problem. If I put an explicit version in it works fine

这个jdk1.7.*.jdk位可能是问题所在。如果我在里面放了一个明确的版本,它就可以正常工作

You can use /usr/libexec/java_home -v 1.7to get the latest 1.7 version installed.

您可以使用/usr/libexec/java_home -v 1.7来安装最新的 1.7 版本。

So to redo your alias, try:

因此,要重做别名,请尝试:

alias j7='JAVA_HOME=`/usr/libexec/java_home -v 1.7`'

Note the back ticks around the java_homebit which will then execute the command to generate the correct path to set JAVA_HOMEto.

请注意java_home位周围的回,然后它将执行命令以生成正确的路径以将JAVA_HOME 设置为。

回答by F. Hauri

Shell aliases could not be used to execute anything before setting environment.

在设置环境之前,无法使用 Shell 别名执行任何操作。

Shell aliases could only hold plain commands, no jockernor sub commands

Shell 别名只能保存普通命令,不能保存 jocker子命令

For doing things like this, you have to write a wrapperscript or at least a function.

为了做这样的事情,你必须编写一个包装脚本或至少一个函数

sudo cat >/usr/local/bin/j7 <<<eof
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.*.jdk/Contents/Home/
java $@
eof
sudo chmod +x /usr/local/bin/j7

or add this function definition to your .bashrc:

或将此函数定义添加到您的.bashrc

j7() {
  export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.*.jdk/Contents/Home/
  java $@
}

Real usefull bash wrapper

真正有用的 bash 包装器

Something like:

就像是:

j7 () {
    local JLIBROOT dir
    # JLIBROOT=/usr/lib/jdk
    JLIBROOT=/Library/Java/JavaVirtualMachines
    while read dir && [ "$dir" = "${dir//1.7.}" ] ;do
        :
      done < <(
          /bin/ls -1trd $JLIBROOT/*
    )
    if [ "$dir" != "${dir//1.7.}" ] ;then
          export JAVA_HOME=$dir/Contents/Home
          java $@
      else
          echo "Version 1.7 not found in '$JLIBROOT'."
      fi
}

could work on my Linux desktop...

可以在我的 Linux 桌面上工作...

回答by Evan Carroll

Using env

使用 env

You can set environmental with the envutility.

您可以使用该env实用程序设置环境。

alias foo='env - X=42 perl -E"say $ENV{X}"'

This sets an alias foowhich declares the environmental variable Xand initializes it to 42before executing perland instructing it to print out the environmental variable X.

这将设置一个别名foo,该别名声明环境变量X42在执行之前将其初始化perl并指示它打印出环境变量X