在 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 别名,好处是如果需要扩展该功能的内容会更容易。