在 shell 别名中设置环境变量
Set an environment variable within a shell alias
在我的系统上,我安装了两个版本的 Java - 有些程序需要 Java 7,有些程序需要 Java 8.
Java 8 是我的系统默认值,所以当我使用 运行 Java 7 个命令时,我一直在使用:
JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.*.jdk/Contents/Home/ \
java_7_program
我想设置一个别名,这样我就可以写
j7 java_7_program
我定义了:
alias j7='JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.*.jdk/Contents/Home/'
但随后 运行 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)
man page(搜索 "Aliases")指出这是作为直接替换完成的。为什么这不起作用?
bash --version
打印 GNU bash, version 4.3.42(1)-release (x86_64-apple-darwin14.5.0)
一个更孤立的例子(减去 java):
$ alias foo='BAR=baz'
$ type foo
foo is aliased to `BAR=baz'
$ foo echo $BAR
[blank line]
jdk1.7.*.jdk
位可能是问题所在。如果我在其中放入一个明确的版本,它就可以正常工作
您可以使用 /usr/libexec/java_home -v 1.7
安装最新的 1.7 版本。
因此,要重做您的别名,请尝试:
alias j7='JAVA_HOME=`/usr/libexec/java_home -v 1.7`'
注意 java_home 位周围的反引号,它将执行命令以生成正确的路径以设置 JAVA_HOME 到.
Shell 在设置环境之前不能使用别名执行任何操作。
Shell 别名只能包含普通命令,没有 jocker 也没有 sub 命令
为了做这样的事情,你必须写一个 wrapper 脚本或者至少一个 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
或将此函数定义添加到您的 .bashrc
:
j7() {
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.*.jdk/Contents/Home/
java $@
}
真正有用的 bash 包装器
类似于:
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
}
可以在我的 Linux 桌面上工作...
回答您的孤立示例:
当你做这样的事情时:
bar=foo my_command
然后 bar
设置在 my_command
的环境中(当前 shell 看不到)。因此,当您这样做时:
bar=stuff
bar=foo my_command "$bar"
因为 $bar
的扩展发生在 my_command
执行之前,所以它就像做:
bar=foo my_command stuff
因为 $bar
被扩展 在 my_command 被分叉之前。这解释了您在示例中获得的 [blank line]
:
$ alias foo='BAR=baz'
$ type foo
foo is aliased to `BAR=baz'
$ foo echo $BAR
[blank line]
只是为了好玩,试试这些:
$ alias foo=BAR=baz
$ BAR=something
$ foo echo "$BAR"
something
有道理吗?
$ alias foo=BAR=baz
$ foo eval 'echo "$BAR"'
baz
这是因为 BAR
是在 eval
的环境中传递的,然后 echo "$BAR"
被扩展......使用预期值(注意单引号!)。
同样,
$ alias foo=BAR=baz
$ foo sh -c 'echo "$BAR"'
baz
使用env
您可以使用 env
实用程序设置环境。
alias foo='env - X=42 perl -E"say $ENV{X}"'
这设置了一个别名foo
,声明环境变量X
并在执行perl
之前将其初始化为42
并指示它打印出环境变量X
.
在我的系统上,我安装了两个版本的 Java - 有些程序需要 Java 7,有些程序需要 Java 8.
Java 8 是我的系统默认值,所以当我使用 运行 Java 7 个命令时,我一直在使用:
JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.*.jdk/Contents/Home/ \
java_7_program
我想设置一个别名,这样我就可以写
j7 java_7_program
我定义了:
alias j7='JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.*.jdk/Contents/Home/'
但随后 运行 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)
man page(搜索 "Aliases")指出这是作为直接替换完成的。为什么这不起作用?
bash --version
打印 GNU bash, version 4.3.42(1)-release (x86_64-apple-darwin14.5.0)
一个更孤立的例子(减去 java):
$ alias foo='BAR=baz'
$ type foo
foo is aliased to `BAR=baz'
$ foo echo $BAR
[blank line]
jdk1.7.*.jdk
位可能是问题所在。如果我在其中放入一个明确的版本,它就可以正常工作
您可以使用 /usr/libexec/java_home -v 1.7
安装最新的 1.7 版本。
因此,要重做您的别名,请尝试:
alias j7='JAVA_HOME=`/usr/libexec/java_home -v 1.7`'
注意 java_home 位周围的反引号,它将执行命令以生成正确的路径以设置 JAVA_HOME 到.
Shell 在设置环境之前不能使用别名执行任何操作。
Shell 别名只能包含普通命令,没有 jocker 也没有 sub 命令
为了做这样的事情,你必须写一个 wrapper 脚本或者至少一个 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
或将此函数定义添加到您的 .bashrc
:
j7() {
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.*.jdk/Contents/Home/
java $@
}
真正有用的 bash 包装器
类似于:
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
}
可以在我的 Linux 桌面上工作...
回答您的孤立示例:
当你做这样的事情时:
bar=foo my_command
然后 bar
设置在 my_command
的环境中(当前 shell 看不到)。因此,当您这样做时:
bar=stuff
bar=foo my_command "$bar"
因为 $bar
的扩展发生在 my_command
执行之前,所以它就像做:
bar=foo my_command stuff
因为 $bar
被扩展 在 my_command 被分叉之前。这解释了您在示例中获得的 [blank line]
:
$ alias foo='BAR=baz'
$ type foo
foo is aliased to `BAR=baz'
$ foo echo $BAR
[blank line]
只是为了好玩,试试这些:
$ alias foo=BAR=baz
$ BAR=something
$ foo echo "$BAR"
something
有道理吗?
$ alias foo=BAR=baz
$ foo eval 'echo "$BAR"'
baz
这是因为 BAR
是在 eval
的环境中传递的,然后 echo "$BAR"
被扩展......使用预期值(注意单引号!)。
同样,
$ alias foo=BAR=baz
$ foo sh -c 'echo "$BAR"'
baz
使用env
您可以使用 env
实用程序设置环境。
alias foo='env - X=42 perl -E"say $ENV{X}"'
这设置了一个别名foo
,声明环境变量X
并在执行perl
之前将其初始化为42
并指示它打印出环境变量X
.