在 git 别名中设置环境变量
Setting an environment variable in a git alias
如果我想在每次使用 git status
时将 foo
的值设置为等于“bar”,我将如何进行?我的第一个想法是为 status="status && foo=bar"
设置一个别名,但是当我尝试这样做并且 echo $foo
时,我没有得到“bar”回显;但是,如果我手动输入 git status && foo=baz
然后 echo $foo
,我的输出是“baz”。为什么我不能在别名中声明变量?
我观察到如果我要调高顺序并且出于某种原因这样做 alias git="foo=bar && git"
如果我尝试任何 git 命令和 echo foo
它等于“bar ".
Git 别名是 运行 by:
- Git本身,如果别名不以
!
开头:在这种情况下你不能设置新的环境变量;或
- a POSIX-compatible shell,如果别名以
!
. 开头
POSIX-compatible shells 允许以两种方式设置环境变量:
VAR=value command
或:
VAR=value; export VAR; command1; command2; ...; commandN
第二个变体可以写成:
export VAR=value; command1; ...; commandN
显式导出的变量是为 所有 以这种方式调用的命令设置的——相对于 VAR=value command
,它只为一个命令设置它——因为这个设置是done in the shell,并持续到 shell 本身退出,然后设置随 shell 退出而消失。因此,如果 x
是 Git 别名:
git x
运行s 那个别名,它可以在别名本身 运行s 的任何命令的持续时间内设置一个环境变量设置。然后 运行 执行这些命令的 shell 退出,所有设置消失。
因此,Git 别名实际上不可能在您用于 运行 的命令行 shell 中设置任何环境变量那个别名。 所有命令都是如此,而不仅仅是Git命令:没有命令可以在任何“外部”shell.
中设置环境变量
有一个逃生口,那就是:当您自己编写 shell 命令时,您就拥有了控制权。例如,您可以编写相当愚蠢的 shell 命令:
export VAR=$(echo value)
括号中的 $(echo value)
被评估,然后它的输出被替换。但这确实意味着如果某个程序 打印 一些你想 保存,可以这样写:
var=$(command)
将局部 shell 变量 var
设置为输出,或者:
export VAR=$(command)
设置 shell 变量并将其导出。 (注意:这里的大写只是约定俗成:导出的局部shell变量按照惯例全部大写,而不导出的局部shell变量是通常全部小写。)
还有第二个逃生口,但使用它有风险:POSIX shells 有一个 eval
命令将文本反馈给 shell口译员。我们可以将其与输出 export VAR1=value1; export VAR2=value2
的程序一起使用:
eval `ssh-agent -s`
此处,ssh-agent
程序设置代理,然后打印几个适当的 export
命令。但是,如果 ssh-agent
程序打印 rm -rf /
,使用 eval ssh-agent -s
将继续删除它能删除的所有文件:这意味着您非常信任 ssh-agent
命令.
您可以使用 shell 别名来创建一些易于输入的命令,例如 gst
,其中包含一个变量-设置操作和一个Git命令:
alias gst='foo=bar && git status'
这不是 Git 别名。这是一个 shell 别名。 POSIX now requires shell aliases(感谢 KamilCuk 的指点)。 Bash 总是有它们,尽管一些非常古老的非 bash shell 可能没有它们。
- 关于您 shell 的行为:
如果您编写以下脚本:
# test.sh:
#!/bin/bash
foo=bar
echo "from script: $foo"
而你运行它,你会看到以下内容:
$ ./test.sh && echo "from cli: $foo"
from script: bar
from cli:
运行使用脚本创建一个全新的、具有自己环境的新进程,foo=bar
在该环境中定义,并在进程退出后被丢弃。
要在当前 shell 中定义设置该变量 ,您必须使用其他方式。
@torek 提到:
- 使用脚本的输出调用
eval ...
- 正在创建 shell 别名
我还要补充:
- 调用函数而不是脚本:
$ mytest () {
foo=bar
echo "from function: $foo"
}
$ mytest && echo "from cli: $foo"
from function: bar
from cli: bar
- 关于 git 别名:
git 别名将始终作为单独的进程执行,如果您想设置一个“比调用长寿”的环境变量,则必须使用其他构造。
例如,您可以在 .bashrc
中定义一个函数:
mystatus () {
git status && foo=bar
}
之后,您将能够从您启动的任何 shell 调用 mystatus
。
如果命令这么简单,它实际上相当于一个 bash 别名,好处是如果需要扩展该功能的内容会更容易。
如果我想在每次使用 git status
时将 foo
的值设置为等于“bar”,我将如何进行?我的第一个想法是为 status="status && foo=bar"
设置一个别名,但是当我尝试这样做并且 echo $foo
时,我没有得到“bar”回显;但是,如果我手动输入 git status && foo=baz
然后 echo $foo
,我的输出是“baz”。为什么我不能在别名中声明变量?
我观察到如果我要调高顺序并且出于某种原因这样做 alias git="foo=bar && git"
如果我尝试任何 git 命令和 echo foo
它等于“bar ".
Git 别名是 运行 by:
- Git本身,如果别名不以
!
开头:在这种情况下你不能设置新的环境变量;或 - a POSIX-compatible shell,如果别名以
!
. 开头
POSIX-compatible shells 允许以两种方式设置环境变量:
VAR=value command
或:
VAR=value; export VAR; command1; command2; ...; commandN
第二个变体可以写成:
export VAR=value; command1; ...; commandN
显式导出的变量是为 所有 以这种方式调用的命令设置的——相对于 VAR=value command
,它只为一个命令设置它——因为这个设置是done in the shell,并持续到 shell 本身退出,然后设置随 shell 退出而消失。因此,如果 x
是 Git 别名:
git x
运行s 那个别名,它可以在别名本身 运行s 的任何命令的持续时间内设置一个环境变量设置。然后 运行 执行这些命令的 shell 退出,所有设置消失。
因此,Git 别名实际上不可能在您用于 运行 的命令行 shell 中设置任何环境变量那个别名。 所有命令都是如此,而不仅仅是Git命令:没有命令可以在任何“外部”shell.
中设置环境变量有一个逃生口,那就是:当您自己编写 shell 命令时,您就拥有了控制权。例如,您可以编写相当愚蠢的 shell 命令:
export VAR=$(echo value)
括号中的 $(echo value)
被评估,然后它的输出被替换。但这确实意味着如果某个程序 打印 一些你想 保存,可以这样写:
var=$(command)
将局部 shell 变量 var
设置为输出,或者:
export VAR=$(command)
设置 shell 变量并将其导出。 (注意:这里的大写只是约定俗成:导出的局部shell变量按照惯例全部大写,而不导出的局部shell变量是通常全部小写。)
还有第二个逃生口,但使用它有风险:POSIX shells 有一个 eval
命令将文本反馈给 shell口译员。我们可以将其与输出 export VAR1=value1; export VAR2=value2
的程序一起使用:
eval `ssh-agent -s`
此处,ssh-agent
程序设置代理,然后打印几个适当的 export
命令。但是,如果 ssh-agent
程序打印 rm -rf /
,使用 eval ssh-agent -s
将继续删除它能删除的所有文件:这意味着您非常信任 ssh-agent
命令.
您可以使用 shell 别名来创建一些易于输入的命令,例如 gst
,其中包含一个变量-设置操作和一个Git命令:
alias gst='foo=bar && git status'
这不是 Git 别名。这是一个 shell 别名。 POSIX now requires shell aliases(感谢 KamilCuk 的指点)。 Bash 总是有它们,尽管一些非常古老的非 bash shell 可能没有它们。
- 关于您 shell 的行为:
如果您编写以下脚本:
# test.sh:
#!/bin/bash
foo=bar
echo "from script: $foo"
而你运行它,你会看到以下内容:
$ ./test.sh && echo "from cli: $foo"
from script: bar
from cli:
运行使用脚本创建一个全新的、具有自己环境的新进程,foo=bar
在该环境中定义,并在进程退出后被丢弃。
要在当前 shell 中定义设置该变量 ,您必须使用其他方式。
@torek 提到:
- 使用脚本的输出调用
eval ...
- 正在创建 shell 别名
我还要补充:
- 调用函数而不是脚本:
$ mytest () {
foo=bar
echo "from function: $foo"
}
$ mytest && echo "from cli: $foo"
from function: bar
from cli: bar
- 关于 git 别名:
git 别名将始终作为单独的进程执行,如果您想设置一个“比调用长寿”的环境变量,则必须使用其他构造。
例如,您可以在 .bashrc
中定义一个函数:
mystatus () {
git status && foo=bar
}
之后,您将能够从您启动的任何 shell 调用 mystatus
。
如果命令这么简单,它实际上相当于一个 bash 别名,好处是如果需要扩展该功能的内容会更容易。