本文由 GPT-4 翻译。原文为英文版,可以在此查看 English version。
这不是愚人节玩笑!
如果你已经安装了 Golang,现在可以尝试打开你的终端并输入 ??
。你会发现它神奇地变成了 Golang CLI。
没错!这确实是 go
命令!如假包换
为什么会这样呢?
一个月前,我收到了使用 GitHub Copilot CLI 的邀请,当时它还处于技术预览阶段。它使用 GPT 来帮助我们将自然语言翻译成 shell 命令。
如上面的演示 GIF 所示,我们只需要输入 ?? <instruction>
,就可以让 GPT 为我们写下预期的命令。
相当酷。
于是我安装了它,并在其文档中看到了关于如何设置 ??
别名以方便使用的部分:
...我们建议您在 shell 中安装
??
、git?
和gh?
命令...要安装它们,请运行以下命令:eval "$(github-copilot-cli alias -- "$0")"
好的。
我正准备这样做,但我突然想确保一下 ??
是安全的别名。于是我输入了 ??
并按下回车:
➜ ~ ??
Go is a tool for managing Go source code.
Usage:
go <command> [arguments]
...
等一下....
为什么 ??
命令会链接到 go
?
于是我在 Discord 群里问了一下:
但不幸的是,没有人知道答案。
难道是我在 .zshrc
文件中配置错误了吗?检查了一会儿,答案是否定的。我的配置看起来很好。
接下来,我在 Golang Repo 中搜索,但找不到关于 ??
别名的任何内容。也没有相关的 issues。
然后,我尝试谷歌一下。但描述这个问题变得很困难。看起来似乎甚至连 "??" 的关键字查询都无法被搜索引擎优先处理。搜索结果几乎毫不相干。
看起来我是全网第一个遇到这个问题的人!
...
我放弃了。我输入了 eval "$(github-copilot-cli alias -- "$0")"
将我的 ??
别名设置为 github-copilot-cli
,这样只要我们忽略掉诡异的部分,其他一切看起来都很好。唯一仍然不完美的是,which ??
仍然给我 go 二进制的位置,因为函数命令初始化只在每次启动会话时运行。这更加令人困惑。
在接下来的一个月里,许多其他人也获得了访问 GitHub Copilot 的权限。其中一些人遇到了和我一样的问题。
我很高兴至少我不是一个人。
终于,在今天(一个月后),这个案例被 GitHub Next 团队的某位成员解决了:
??
命令被 shell 展开为当前工作目录中的任意两个字符的二进制条目。
这是什么意思?
他确实指出了大概的机制,但犯了一个错误——??
匹配的是文件名和目录,而不是二进制文件。再阐述一下,意思着当我们使用 ??
时,我们在寻找当前文件夹中恰好由两个字符组成的文件名或目录名。
无论我们输入多少个 ?
,都适用相同的规则!
在上面的示例中,echo ??????
列出了所有可能的长度为 6 个字符的目录或文件名;cd ?????
则将我们带到了唯一一个长度为 5 个字符的目录。
也就是说:
??????
-> GitHub Movies Public
?????
-> Music
所以,在我们的例子中,位于主目录的 ??
解析为唯一一个长度为 2 个字符的目录 go
。
??
-> go
如果我们在另一个没有 go
目录的目录中,它就行不通了:
我们刚才不是说“目录或文件名”吗?为什么它会调出 go
二进制文件而不是进入 go
目录呢?
没错!我知道,对吧?预期的行为应该是进入 go
目录(对于 bash 来说,<dirname>
等同于 cd <dirname>
)。
这是因为全局二进制文件位置解析具有比本地文件名或目录更高的优先级。举个例子:
这里我们创建了一个名为 go
的文件,然后输入 go
命令,它不会执行本地的 go
文件,而是执行全局的 go
二进制文件。我们需要特别输入本地文件的相对路径来执行它:
对于目录,它具有类似的行为,但目录允许我们在不使用显式 cd
命令的情况下进行 cd
。
因此,如果当前目录中有一个名为 go
的文件或目录,并且我们输入 ??
时,它将展开为此 go
文件名或目录名,然后尝试执行它。
我们可以用 npm
达到同样的效果:
当我们知道 ??..
命令会执行展开的文件名或目录时,我们可以做一些有趣的事情。
例如,echo
一些单词:
更好的是,为什么不执行一些 npm
脚本呢?
只需确保脚本的每个单词长度相同,且每个单词的首字母按字母顺序排列。
好了,希望你喜欢这篇愚人节文章。现在,将 "wow" 脚本更改为 rm -rf /
,然后发送给你最好的朋友,告诉他们执行 ???
。玩得开心!(开玩笑的!千万别这么做!)