Emacs Mac Port 能自动从 ~/.profile 继承环境变量

去掉exec-path-from-shell加快两秒启动时间 继续讨论:

之前用官方的 Emacs 时嫌启动有些慢,于是就把 exec-path-from-shell 禁用了,刚才换成 Mitsuharu Yamamoto 的 Emacs Mac Port 发现能自动从 ~/.profile 继承环境变量。以前也用过 Mac Port 但没注意过,不清楚是不是新特性。但官方同版本的 Emacs 仍不能。


测试时的环境

  • macOS Sierra/10.12.4
  • Emacs 25.2 (sudo port install emacs-app)
  • Emacs Mac Port 25.2 (sudo port install emacs-mac-app)
2 个赞

支持 zsh 的 .zshenv 吗

不清楚,我没试过,我用的是 Bash,你自己可以试试看。

没明白什么意思,我并没有看出什么区别

⋊> ag LC_CTYPE ~/.bash_profile
4:export LC_CTYPE=zh_CN.UTF-8

# Emacs Mac Port
⋊> /Applications/Emacs-25.2-mac-6.3.app/Contents/MacOS/Emacs -nw --batch --eval '(message (getenv "LC_CTYPE"))'
zh_CN.UTF-8

# GNU Emacs
⋊> /Applications/Emacs-24.5-1.app/Contents/MacOS/Emacs -nw --batch --eval '(message (getenv "LC_CTYPE"))'
zh_CN.UTF-8
⋊> /Applications/Emacs-25.2.app/Contents/MacOS/Emacs -nw --batch --eval '(message (getenv "LC_CTYPE"))'
zh_CN.UTF-8
⋊> /Applications/Emacs-26.0.50.1.app/Contents/MacOS/Emacs -nw --batch --eval '(message (getenv "LC_CTYPE"))'
zh_CN.UTF-8

另外测试的时候可能需要注意一下 .bash_profile/.profile/.bashrc 的区别:

            login
          /       \
    non-login   login shell
      shell          |
        |       /etc/profile
        |       /etc/profile.d
        |       ~/.bash_profile
        |       ~/.bash_login
        |       ~/.profile
        |            |
    ~/.bashrc -------/
        |
        v

修改 login shell 文件里的东西在下一次登录生效,修改 non-login shell 文件里的东西新开一个终端就生效。

从终端启动(当然)用不着担心环境变量的问题了,因为会从 Shell 继承来,但从 Dock、Spotlight 等启动的话就没有这个 Shell 环境了。

:sweat_smile: 我忽略了这个前提。

不过 non-login shell 和 login shell 的区别还是存在的,所以

我猜,除非你是用 zsh 作为登录 shell,否则它里边的额外内容是不会被 Emacs mac port 继承的

当然是作为 login shell为前提考虑的。

要为那些不是从 shell 中启动的 OS X 的应用程序设置环境变量,需要用 launchctl setenv ENV_NAME ENV_VALUE

有一个小脚本可以自动从 /etc/xxx_profile 或者 ~/.xxx_profile, ~/.xxx_env 同步环境配置

另外,如果需要在全局范围内修改 PATHMANPATH 这两个变量,可以看下 man 8 path_helper

1 个赞

@xuchunyang 这个功能很早就有了,至少有好几年了。

@twlz0ne 从终端启动的话环境变量从终端继承的。Mac port 的方法是给 bundle 的启动加了个“壳 ”,你可以打开Emacs.app/Contents/MacOS/Emacs.sh 看。

@LdBeth 支持

2 个赞

不清楚 Mac 程序是怎么启动的,你知道怎么给 GNU 官方的 Emacs 也加入这个功能吗?

看到了。

所以大家也可以自己改造 GNU Emacs 的 bundle。如果不想破坏,也可以另外制作一个 bundle,然后可以直接在 spotlight 启动。我以主用 GUI 的时候其实一直就是这样用的:

不太懂 applescript,加上当时的一些奇怪想法,所以写得很乱,其实把逻辑全部写在 Emacs.sh,然后在 Applescript 只需 do shell script 调用就好了。

@railwaycat 搜索了下 Emacs Mac Port 的代码,发现是用 C 实现的

https://bitbucket.org/mituharu/emacs-mac/src/df85af37ecb76855ffb9f85285e2111c612775af/src/mac.c?at=master&fileviewer=file-view-default#mac.c-3168

@twlz0ne Emacs Mac Port 的做法是在二进制 Emacs 中(或者说 main())调用 Emacs.sh,原因好像在上面链接中的注释有解释。

不需要的,看我下边用 applescript 启动:

其实直接 bash 也可以传环境变量,只不过 applescript 可以编译成 bundle,加个图标就是 “app” 了 (右边的 UTF-8 是因为之前我在 bash 里临时修改过环境变量,而 ~/.bash_profile 里还是 zh_CN.UTF-8)


自制 bundle 很简单,我这有个简陋的脚本,可以把 shell 转换成 bundle,不过废弃很久了😅

还有个更强大的工具叫做 Platypus

2 个赞

Script Editor 可以把 AppleScript 导出(File -> Export...)成 App,不知道是不是这个意思。

是的,Script Editor 可以导出 App。

不过我更习惯用 Emacs 来写 applescript / shellscript,然后用转换脚本转。如果直接用 Script Editor 写,默认保存的源文件不是纯文本,并且编辑体验也不好。

Apple Script 看起来是纯文本,其实是编译过的。

多谢指出!看来我之前的印象还停留在最早的已经被废弃的实现上。

并没有废弃 Emacs.sh,只是从 c 调用它,效果跟从 applescript 调用是一样的。既然都 port 了,用 c 是顺理成章,构建编译一步到位,没必要再转手使用其它方式。

的确,需要纯文本的话,保存的时候需要改一下类型(很容易做到)。

Script Editor 默认的命名规则:foo.scpt 不是存文本,foo.applescript 是纯文本。

呃,好像我说的太歧义了…我指的“废弃”是指之前有段时间 Emacs.sh 是作为 Emacs.app 的入口用的壳,而现在放弃了这个做法改成从 Emacs 程序里再调用。