diff --git a/.changeset/quiet-mice-skip-dms.md b/.changeset/quiet-mice-skip-dms.md new file mode 100644 index 000000000..9ba569d9f --- /dev/null +++ b/.changeset/quiet-mice-skip-dms.md @@ -0,0 +1,5 @@ +--- +"fnm": patch +--- + +guard the documented shell setup snippets (and the installer-appended ones) behind an interactive-shell check so non-interactive logins, such as display managers scraping env vars at session start, no longer leak a stale `fnm_multishells` path into `$PATH`. Closes #1551. diff --git a/.ci/install.sh b/.ci/install.sh index 9a9647748..e89be5572 100755 --- a/.ci/install.sh +++ b/.ci/install.sh @@ -177,7 +177,10 @@ setup_shell() { if [ "$USE_HOMEBREW" != "true" ]; then echo ' export PATH="$FNM_PATH:$PATH"' fi - echo ' eval "$(fnm env --shell zsh)"' + echo ' # only initialize for interactive shells; non-interactive logins' + echo ' # (e.g. display managers scraping env vars) would otherwise leak a' + echo ' # stale multishell into the session PATH.' + echo ' [[ $- == *i* ]] && eval "$(fnm env --shell zsh)"' echo 'fi' } | tee -a "$CONF_FILE" @@ -193,7 +196,10 @@ setup_shell() { if [ "$USE_HOMEBREW" != "true" ]; then echo ' set PATH "$FNM_PATH" $PATH' fi - echo ' fnm env --shell fish | source' + echo ' # only initialize for interactive shells; non-interactive logins' + echo ' # (e.g. display managers scraping env vars) would otherwise leak a' + echo ' # stale multishell into the session PATH.' + echo ' status is-interactive; and fnm env --shell fish | source' echo 'end' } | tee -a "$CONF_FILE" @@ -213,7 +219,10 @@ setup_shell() { if [ "$USE_HOMEBREW" != "true" ]; then echo ' export PATH="$FNM_PATH:$PATH"' fi - echo ' eval "$(fnm env --shell bash)"' + echo ' # only initialize for interactive shells; non-interactive logins' + echo ' # (e.g. display managers scraping env vars) would otherwise leak a' + echo ' # stale multishell into the session PATH.' + echo ' [[ $- == *i* ]] && eval "$(fnm env --shell bash)"' echo 'fi' } | tee -a "$CONF_FILE" diff --git a/.ci/test_installation_script.sh b/.ci/test_installation_script.sh index cee4b323f..025247f86 100755 --- a/.ci/test_installation_script.sh +++ b/.ci/test_installation_script.sh @@ -15,12 +15,14 @@ echo "---" echo "PATH=$PATH" echo "---" -$SHELL_TO_RUN -c " +# Use an interactive shell (-i) so the appended fnm setup, which is now guarded +# by an interactive-shell check, actually runs when the profile is sourced. +$SHELL_TO_RUN -i -c " . $PROFILE_FILE fnm --version " -$SHELL_TO_RUN -c " +$SHELL_TO_RUN -i -c " . $PROFILE_FILE fnm install 12.5.0 fnm ls | grep 12.5.0 @@ -28,7 +30,7 @@ $SHELL_TO_RUN -c " echo 'fnm ls worked.' " -$SHELL_TO_RUN -c " +$SHELL_TO_RUN -i -c " . $PROFILE_FILE fnm use 12.5.0 node --version | grep 12.5.0 diff --git a/README.md b/README.md index f5dbf9320..ed370bdc8 100644 --- a/README.md +++ b/README.md @@ -158,7 +158,9 @@ Check out the following guides for the shell you use: Add the following to your `.bashrc` profile: ```bash -eval "$(fnm env --use-on-cd --shell bash)" +# only run for interactive shells; non-interactive logins (e.g. display managers +# scraping env vars) would otherwise leave a stale multishell in the session PATH. +[[ $- == *i* ]] && eval "$(fnm env --use-on-cd --shell bash)" ``` #### Zsh @@ -166,7 +168,9 @@ eval "$(fnm env --use-on-cd --shell bash)" Add the following to your `.zshrc` profile: ```zsh -eval "$(fnm env --use-on-cd --shell zsh)" +# only run for interactive shells; non-interactive logins (e.g. display managers +# scraping env vars) would otherwise leave a stale multishell in the session PATH. +[[ $- == *i* ]] && eval "$(fnm env --use-on-cd --shell zsh)" ``` #### Fish shell @@ -174,7 +178,9 @@ eval "$(fnm env --use-on-cd --shell zsh)" Create `~/.config/fish/conf.d/fnm.fish` and add this line to it: ```fish -fnm env --use-on-cd --shell fish | source +# only run for interactive shells; non-interactive logins (e.g. display managers +# scraping env vars) would otherwise leave a stale multishell in the session PATH. +status is-interactive; and fnm env --use-on-cd --shell fish | source ``` #### PowerShell