Please fix the setup script for macOS
On macOS there setup script mentioned bash completions, but it should be zsh completions instead. An easy fix, but it will save hours for many macOS users. Please fix it.
After running the following command to install NVM.
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.2/install.sh | bashmy .zshrc file had the following added.
export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completionAfter restarting the terminal, it appeared.
zsh compinit: insecure directories, run compaudit for list. Ignore insecure directories and continue [y] or abort compinit [n]?After changing
bash_completiontozsh_completion, the error disappeared.
Originally posted by @amlzq in #2361
Not all Mac OS users use zsh, so it definitely shouldn’t do it by platform.
@ljharb said:
Not all Mac OS users use zsh, so it definitely shouldn’t do it by platform.
I think last 2-3 years macOS ships with zsh. So you always can check if zsh is available and use one output, with a fallback to bash. Seems an easy check
Yes, that's true, but if you've continuously migrated your Mac environment from prior to that, then you'll stay on bash, as I have.
zsh is always available now, that can't be used to make a choice.
I have a .bashrc, .bash_profile, and .zshrc present, but bash is my default. What logic would you suggest that can select "bash" for me but "zsh" for you?
https://support.apple.com/en-us/102360
zsh (Z shell) is the default shell for all newly created user accounts, starting with macOS Catalina.
https://en.wikipedia.org/wiki/MacOS_Catalina
macOS Catalina [was] released to the public on October 7, 2019
https://endoflife.date/macos
macOS 10.15 (Catalina) support ended 12 Sep 2022
if you've continuously migrated your Mac environment from prior to that
Not everybody is as old as we are 😉
I have a .bashrc, .bash_profile, and .zshrc present, but bash is my default. What logic would you suggest that can select "bash" for me but "zsh" for you?
You always can see in which shell you run the installation script (bash, zsh, etc), right? Depending on it you can write to terminal the correct instructions. I think you can see how other projects achieve this. Or if no luck with detection, write few possible lines - each for each supported shell.
https://stackoverflow.com/questions/3327013/how-to-determine-the-current-interactive-shell-that-im-in-command-line
Unfortunately, the output of ps -p $$ is not standardized and some terminals report it incorrectly.
$BASH or $ZSH_NAME usually indicate the shell used but it is not reliable either.
But I think a 90% solution is better then doing nothing:
If $ZSH_NAME or ps -p $$ contains the string zsh do the zsh installation otherwise do the bash installation.
I'd be happy to review a PR that did that - noting that the install script must always run in bash.
I experimented a little:
$ sw_vers
ProductName: macOS
ProductVersion: 12.7.6
BuildVersion: 21H1320
$ ps -p $$
PID TTY TIME CMD
77576 ttys002 0:00.20 -zsh
$ echo $SHELL
/bin/zsh
$ echo $ZSH_NAME
zsh
$ mkdir /tmp/test && cd "$_"
$ printf '#!/usr/bin/env bash\necho $(ps -p $$)\necho $SHELL\necho $BASH\necho $ZSH_NAME\n' >install.sh
$ chmod u+x install.sh
$ curl -so- file:///tmp/test/install.sh | zsh
PID TTY TIME CMD 78615 ttys001 0:00.01 zsh
/bin/zsh
zsh
$ curl -so- file:///tmp/test/install.sh | bash
PID TTY TIME CMD 78651 ttys001 0:00.01 bash
/bin/zsh
/usr/local/bin/bash
$ zsh -c 'curl -so- curl -so- file:///tmp/test/install.sh | zsh'
PID TTY TIME CMD 78691 ttys001 0:00.01 zsh
/bin/zsh
zsh
$ zsh -c 'curl -so- curl -so- file:///tmp/test/install.sh | bash'
PID TTY TIME CMD 78702 ttys001 0:00.01 bash
/bin/zsh
/usr/local/bin/bash
$ bash -c 'curl -so- curl -so- file:///tmp/test/install.sh | zsh'
PID TTY TIME CMD 78767 ttys001 0:00.01 zsh
/bin/zsh
zsh
$ bash -c 'curl -so- curl -so- file:///tmp/test/install.sh | bash'
PID TTY TIME CMD 78755 ttys001 0:00.01 bash
/bin/zsh
/usr/local/bin/bash
$ docker run -it --rm -v /tmp/test:/tmp/test ubuntu:noble-20250404 bash
# apt-get -y update && apt-get -y install curl
# curl -so- file:///tmp/test/install.sh | bash
PID TTY TIME CMD 2927 pts/0 00:00:00 bash
/bin/bash
/usr/bin/bash
# exit
$ docker run -it --rm -v /tmp/test:/tmp/test ubuntu:noble-20250404 bash
# apt-get -y update && apt-get -y install curl zsh
# zsh
# ps -p $$
PID TTY TIME CMD
3025 pts/0 00:00:00 zsh
# curl -so- file:///tmp/test/install.sh | bash
PID TTY TIME CMD 3047 pts/0 00:00:00 bash
/bin/bash
/usr/bin/bash
# curl -so- file:///tmp/test/install.sh | zsh
PID TTY TIME CMD 3050 pts/0 00:00:00 zsh
zsh
# exit
# zsh -c 'curl -so- curl -so- file:///tmp/test/install.sh | bash'
PID TTY TIME CMD 3056 pts/0 00:00:00 bash
/bin/bash
/usr/bin/bash
# zsh -c 'curl -so- curl -so- file:///tmp/test/install.sh | zsh'
PID TTY TIME CMD 3061 pts/0 00:00:00 zsh
zsh
As expected, a mess 🫣
There are three options:
- do nothing
- if one of
ps -p $$,$SHELL, or$ZSH_NAMEcontainszshthen install zsh completions instead of bash completions - same as 2. but also mention
curl .../install.sh | zshin docs
2. and 3. could either install zsh completions immediately or ask something along the lines "It seems that you are you using zsh; do you want to install zsh completions instead of bash completions?"
I do not think zsh_completion is a thing, and modifying the name of the script in your .zshrc to it is not a real fix. I ran into this on Apple Silicon with a two-user setup where some Homebrew completions have mixed ownership.
The issue is that NVM's bash_completion script calls compinit during shell initialization, but this happens before the shell has properly set up the completion system, causing zsh to flag the mixed-ownership completion files as insecure and abort initialization.
My workaround is to temporarily disable the security check just during NVM initialization in .zshrc:
ZSH_DISABLE_COMPFIX=true
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
unset ZSH_DISABLE_COMPFIX
This allows the completion system to initialize properly while maintaining security for any future completion loading.
perhaps that's something we could do inside bash_completion, around the compinit call?
Sorry gang: I'm new to this stuff, and can't figure out how to stop getting the:
zsh compinit: insecure directories, run compaudit for list. Ignore insecure directories and continue [y] or abort compinit [n]? y%
Every time I open the terminal. I know that the installation script hasn't been fixed yet, but can someone tell me what I (a beginner) have to do to STOP seeing this message every time I open Terminal? (I've tried CodyPotter's .zshrc code in post 12, but it doesn't seem to do anything... but let's not rule out user error... I don't know how to do this!)
Hey guys, I was taking a look at this because I use zsh in both my linux and mac machine and I've never had such issue. After some reviewing I might have found a solution and it is covered in this Stackoverflow post and also in this legendary zsh forum email.
There are some points to cover:
First the problem is not related to nvm itself.
Second, making the change from "$NVM_DIR/bash_completion" to "$NVM_DIR/zsh_completion" removed the errors because there is no such file called zsh_completion, the problem is not within the name of the file but with the function the file is execution. If you execute tail -18 $NVM_DIR/bash_completion you will see the following output:
# complete is a bash builtin, but recent versions of ZSH come with a function
# called bashcompinit that will create a complete in ZSH. If the user is in
# ZSH, load and run bashcompinit before calling the complete function.
if [[ -n ${ZSH_VERSION-} ]]; then
# First calling compinit (only if not called yet!)
# and then bashcompinit as mentioned by zsh man page.
if ! command -v compinit > /dev/null; then
autoload -U +X compinit && if [[ ${ZSH_DISABLE_COMPFIX-} = true ]]; then
compinit -u
else
compinit
fi
fi
autoload -U +X bashcompinit && bashcompinit
fi
complete -o default -F __nvm nvm
At the end of the bash_completion file it is being executed the compinit command which is related to error being thrown:
zsh compinit: insecure directories, run compaudit for list.
Ignore insecure directories and continue [y] or abort compinit [n]? y%
What you could do is, run the following commands as mentioned in both stackoverflow post and zsh user email:
sudo chmod -R 755 /usr/local/share/zsh/site-functions
# If the chmod didn't worked try this too:
# The -L param is used to update the symlinks if there is any:
# sudo chown -RL root:staff /usr/local/share/zsh
For more info I really recommend reading the zsh user email and stackoverflow post (and also the commentaries) mentioned early. Hope this helps