fish shell 函数中的 Eval 工作异常

Eval in fish shell function working strange

我试图对 docker 的命令进行包装以更改 docker 机器上下文。这是命令和输出:

docker-machine env dev

set -x DOCKER_TLS_VERIFY "1";
set -x DOCKER_HOST "tcp://192.168.99.101:2376";
set -x DOCKER_CERT_PATH "/Users/sandric/.docker/machine/machines/dev";
set -x DOCKER_MACHINE_NAME "dev";
# Run this command to configure your shell:
# eval (docker-machine env dev)

函数代码,我放在.config/fish/config.fish:

function cdm
  eval (docker-machine env $argv)
end

因此,当尝试在新会话中 运行 cdm 时,功能已评估,但上下文没有改变。但是,如果我 运行:

eval (docker-machine env default)

从命令提示符,并尝试 运行 cdm 使用不同的参数 - 一切正常。所以我怀疑它与这个试图从 fish 函数设置的命令的现有环境变量有关。我什至尝试尝试将该函数更改为别名(这也是我得到的 fish 函数的别名)命令常量而不是参数:

alias cdm "eval (docker-machine env dev)"

它的工作原理是一样的——如果我在新打开的会话中首先运行这个别名,它不会改变环境变量,但是如果我从命令提示符运行评估代码——在那个别名之后按预期工作。

那么,这是怎么回事,有人有什么想法吗?

看起来 Docker 的输出没有指定明确的范围,所以当你 运行 它在你的函数中并且那些变量没有在其他地方定义时,它们最终会在函数的作用域。

但是,如果您在命令提示符下 运行 相同的代码,您最终会得到在全局范围内定义的变量,然后由函数中的 set 更新这些变量。

参见documentation for set

The scoping rules when creating or updating a variable are:

  1. If a variable is explicitly set to either universal, global or local, that setting will be honored. If a variable of the same name exists in a different scope, that variable will not be changed.

  2. If a variable is not explicitly set to be either universal, global or local, but has been previously defined, the previous variable scope is used.

  3. If a variable is not explicitly set to be either universal, global or local and has never before been defined, the variable will be local to the currently executing function. Note that this is different from using the -l or --local flag. If one of those flags is used, the variable will be local to the most inner currently executing block, while without these the variable will be local to the function. If no function is executing, the variable will be global.

要解决此问题,请尝试使用 --no-scope-shadowing 定义您的 cdm 函数(虽然这似乎有效,但我不确定是否应该如此)。