原因
macOSのVSCodeが起動されるとログインシェルが起動され、さらにターミナルを起動するときもう一度ログインシェルが起動されるので、~/.zprofile等が2回読み込まれるらしい。
This can happen on macOS because of how the terminal launches using VS Code's environment. When VS Code launches for the first time, to source your "development environment," it launches your configured shell as a login shell, which runs your ~/.profile/~/.bash_profile/~/.zprofile scripts. Now when the terminal launches, it also runs as a login shell, which will put the standard paths to the front (for example, /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin) and reinitialize your shell environment.
対策
1. ~/.zshenvで$PATHを空にしておく方法
zshの初期化ファイル読み込み順は
# 1. /etc/zshenv
# 2. ~/.zshenv
# 3. [login mode]
# i. /etc/zprofile
# ii. ~/.zprofile
# 4. [interactive]
# i. /etc/zshrc
# ii. ~/.zshrc
# 5. [login mode]
# i. /etc/zlogin
# ii. ~/.zlogin
であり、/etc/zshenvは存在しないので、~/.zshenvで$PATHを空にしておけば良い。
# ターミナルエミュレータがVSCodeかつzshがログインシェル
if [ "$TERM_PROGRAM" = "vscode" ] && [[ -o login ]]; then
PATH=
fi
2. inheritEnv: falseにする方法
VSCode公式ドキュメントに
There are two direct fixes for this. The first is to set "terminal.integrated.inheritEnv": false, which will strip most environment variables from the terminal's environment, except for some important ones (like HOME, SHELL, TMPDIR, etc.).
とあったので
"terminal.integrated.inheritEnv": false
を設定してみたが、自分の環境ではうまくいかなかった。
3. VSCodeターミナル内で起動するシェルを非ログインシェルにする方法
args
の中の"-l"
を消すことで非ログインシェルにする方法もある。
こうするとターミナル起動時に~/.zprofile等が実行されなくなることには注意。
非ログインシェルでも~/.zshrcは読み込まれるので、その中でPATHを追加していたら二重になることに注意。
"terminal.integrated.profiles.osx": {
...
"zsh": {
"path": "zsh",
"args": [], // -l を消した
},