Xcode 一个有意思的机制 / 小型 brew-clang 启动器

最近觉得终端里面输 python 出来的竟然是 python2 很不爽,然后就想用个软链接把 /usr/local/bin/python 指到 /usr/local/bin/python3

1
$ sudo ln -s /usr/local/bin/python3 /usr/local/bin/python

完事,然后:

好怪哦

弄了半天不知道怎么回事,最后群里问了问,有大佬解释是这个 Xcode CommandLine Tools 提供的 python 会根据传入的程序名称决定行为,argv[0] 是 python 就当 python2 执行

软链接没问题,文件确实是一样的

换个名字就执行不了了

其实我应该自己早点发现这个问题的,之前刷知乎刷到过 clang/clang++ 也是一样的原理,共用一个执行文件,根据传入的 argv[0] 决定是否链接 libc++ 库等

还是没想到这里去


最后用了个 alias ,不折腾软链接了

最后还是用上了 conda 管理环境,删掉了 /usr/local/bin 里面的python/pip等。

等等……

啊?

所以 Xcode CLT 是把所有的命令链接到同一个二进制文件,然后再根据调用时的名字决定执行具体哪个程序?


利用类似的原理,写了个 brew-clang 启动器

1
2
3
4
5
6
7
#!/usr/bin/env zsh

prefix="/opt/homebrew/Cellar/llvm"
ver=($(ls -vr $prefix))
dir="$prefix/${ver[1]}/bin/"
# 运行 llvm/(version)/bin/ 目录下的同名程序
$dir/$(basename $0) $argv

将这个脚本随便保存个名字,再创建一些链接命名为想要导出的命令即可

使用效果: