Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detect shell type from $SHELL variable instead of .$SHELLrc files #765

Merged
merged 1 commit into from
Jul 21, 2015

Conversation

CristianCantoro
Copy link
Contributor

As per commit message.
I am using zsh on Ubuntu, but I am keeping also the default .bashrc that gets shipped with Ubuntu in my home folder. As of now, the nvm "loading" configuration gets added to $HOME/.bashrc because the check on .bashrc is encountered before the check on .zshrc.

basename is part of the GNU coreutils so it should be widely available and this should work also on other OSes.

Testing the various shells

(sh is dash on my system)

Launch from zsh

[~/extra/nvm/nvm]$ cat ./install.sh | sh
=> Downloading nvm from git to '/home/cristian/.nvm'
=> Cloning into '/home/cristian/.nvm'...
remote: Counting objects: 3693, done.
remote: Total 3693 (delta 0), reused 0 (delta 0), pack-reused 3693
Receiving objects: 100% (3693/3693), 827.00 KiB | 0 bytes/s, done.
Resolving deltas: 100% (2132/2132), done.
Checking connectivity... done.
* (detached from v0.25.4)

=> Appending source string to /home/cristian/.zshrc
=> Close and reopen your terminal to start using nvm

Launch from bash

$ bash
cristian@wash:~/extra/nvm/nvm$ cat ./install.sh | sh
=> Downloading nvm from git to '/home/cristian/.nvm'
=> Cloning into '/home/cristian/.nvm'...
remote: Counting objects: 3693, done.
remote: Total 3693 (delta 0), reused 0 (delta 0), pack-reused 3693
Receiving objects: 100% (3693/3693), 827.00 KiB | 0 bytes/s, done.
Resolving deltas: 100% (2132/2132), done.
Checking connectivity... done.
* (detached from v0.25.4)

=> Source string already in /home/cristian/.zshrc
=> Close and reopen your terminal to start using nvm

Launch from ksh

$ ksh
$ cat ./install.sh | sh
=> Downloading nvm from git to '/home/cristian/.nvm'
=> Cloning into '/home/cristian/.nvm'...
remote: Counting objects: 3693, done.
remote: Total 3693 (delta 0), reused 0 (delta 0), pack-reused 3693
Receiving objects: 100% (3693/3693), 827.00 KiB | 1.41 MiB/s, done.
Resolving deltas: 100% (2132/2132), done.
Checking connectivity... done.
* (detached from v0.25.4)

=> Source string already in /home/cristian/.zshrc
=> Close and reopen your terminal to start using nvm

Launch from sh

$ sh
$ cat ./install.sh | sh
=> Downloading nvm from git to '/home/cristian/.nvm'
=> Cloning into '/home/cristian/.nvm'...
remote: Counting objects: 3693, done.
remote: Total 3693 (delta 0), reused 0 (delta 0), pack-reused 3693
Receiving objects: 100% (3693/3693), 827.00 KiB | 0 bytes/s, done.
Resolving deltas: 100% (2132/2132), done.
Checking connectivity... done.
* (detached from v0.25.4)
  master

=> Source string already in /home/cristian/.zshrc
=> Close and reopen your terminal to start using nvm

@ljharb
Copy link
Member

ljharb commented Jun 12, 2015

Thanks for the contribution!

I am all for improving profile file detection as there's a number of issues open about it. I'm concerned about changing this though, so I'll want to test it on as many configurations as possible before merging it.

@ljharb ljharb added the installing nvm: profile detection Issues with nvm's own install script, related to figuring out the right profile file. label Jun 12, 2015
@ljharb
Copy link
Member

ljharb commented Jun 12, 2015

(Note that install.sh must be piped to bash, not sh, and that this has to work correctly with all of zsh, bash, dash, sh, and ksh)

@CristianCantoro
Copy link
Contributor Author

@ljharb, I had also tested that possibility, but omitted it before.

Anyway, I believe that even launching the script from dash (i.e. ... install.sh | sh) gets it executed in bash because of the #!/bin/bash line at the beginning of the script (but I may be wrong, this things are always more complicated than they seem).

Also note that since my $SHELL env variable remains the same even when I launch a different shell the profile detected remains .zshrc, which is the intended behaviour, IMHO.

Here's the test executing the script with bash.

Piping to bash

zsh

[~/extra/nvm/nvm]$ cat ./install.sh | bash
=> Downloading nvm from git to '/home/cristian/.nvm'
=> Cloning into '/home/cristian/.nvm'...
remote: Counting objects: 3693, done.
remote: Total 3693 (delta 0), reused 0 (delta 0), pack-reused 3693
Receiving objects: 100% (3693/3693), 827.00 KiB | 0 bytes/s, done.
Resolving deltas: 100% (2132/2132), done.
Checking connectivity... done.
* (detached from v0.25.4)

=> Source string already in /home/cristian/.zshrc
=> Close and reopen your terminal to start using nvm

bash

$ bash
cristian@wash:~/extra/nvm/nvm$ cat ./install.sh | bash
=> Downloading nvm from git to '/home/cristian/.nvm'
=> Cloning into '/home/cristian/.nvm'...
remote: Counting objects: 3693, done.
remote: Total 3693 (delta 0), reused 0 (delta 0), pack-reused 3693
Receiving objects: 100% (3693/3693), 827.00 KiB | 0 bytes/s, done.
Resolving deltas: 100% (2132/2132), done.
Checking connectivity... done.
* (detached from v0.25.4)

=> Source string already in /home/cristian/.zshrc
=> Close and reopen your terminal to start using nvm

ksh

$ ksh
$ cat ./install.sh | bash
=> Downloading nvm from git to '/home/cristian/.nvm'
=> Cloning into '/home/cristian/.nvm'...
remote: Counting objects: 3693, done.
remote: Total 3693 (delta 0), reused 0 (delta 0), pack-reused 3693
Receiving objects: 100% (3693/3693), 827.00 KiB | 0 bytes/s, done.
Resolving deltas: 100% (2132/2132), done.
Checking connectivity... done.
* (detached from v0.25.4)

=> Source string already in /home/cristian/.zshrc
=> Close and reopen your terminal to start using nvm

sh (dash)

$ sh
$ cat ./install.sh | bash
=> Downloading nvm from git to '/home/cristian/.nvm'
=> Cloning into '/home/cristian/.nvm'...
remote: Counting objects: 3693, done.
remote: Total 3693 (delta 0), reused 0 (delta 0), pack-reused 3693
Receiving objects: 100% (3693/3693), 827.00 KiB | 0 bytes/s, done.
Resolving deltas: 100% (2132/2132), done.
Checking connectivity... done.
* (detached from v0.25.4)

=> Source string already in /home/cristian/.zshrc
=> Close and reopen your terminal to start using nvm

@ljharb
Copy link
Member

ljharb commented Jun 12, 2015

What about on a Mac, where by default, bashrc isn't sourced, and bash_profile is? On a fresh Mac user account I suspect this will break. Perhaps you want to also check for the file's existence as well as the shell type?

@CristianCantoro
Copy link
Contributor Author

@ljharb, I have changed my pull request and rebased.

Here's the test.

Piping to sh

zsh to sh

zsh -c "cat /home/cristian/extra/nvm/nvm/install.sh | sh; rm -rf "/home/cristian/.nvm";  exit;"
=> Downloading nvm from git to '/home/cristian/.nvm'
=> Cloning into '/home/cristian/.nvm'...
remote: Counting objects: 3693, done.
remote: Total 3693 (delta 0), reused 0 (delta 0), pack-reused 3693
Receiving objects: 100% (3693/3693), 827.00 KiB | 1.48 MiB/s, done.
Resolving deltas: 100% (2132/2132), done.
Checking connectivity... done.
* (detached from v0.25.4)
  master

=> Source string already in /home/cristian/.zshrc
=> Close and reopen your terminal to start using nvm

bash to sh

bash -c "cat /home/cristian/extra/nvm/nvm/install.sh | sh; rm -rf "/home/cristian/.nvm";  exit;"
=> Downloading nvm from git to '/home/cristian/.nvm'
=> Cloning into '/home/cristian/.nvm'...
remote: Counting objects: 3693, done.
remote: Total 3693 (delta 0), reused 0 (delta 0), pack-reused 3693
Receiving objects: 100% (3693/3693), 827.00 KiB | 1.27 MiB/s, done.
Resolving deltas: 100% (2132/2132), done.
Checking connectivity... done.
* (detached from v0.25.4)
  master

=> Source string already in /home/cristian/.zshrc
=> Close and reopen your terminal to start using nvm

ksh to sh

ksh -c "cat /home/cristian/extra/nvm/nvm/install.sh | sh; rm -rf "/home/cristian/.nvm";  exit;"
=> Downloading nvm from git to '/home/cristian/.nvm'
=> Cloning into '/home/cristian/.nvm'...
remote: Counting objects: 3693, done.
remote: Total 3693 (delta 0), reused 0 (delta 0), pack-reused 3693
Receiving objects: 100% (3693/3693), 827.00 KiB | 653.00 KiB/s, done.
Resolving deltas: 100% (2132/2132), done.
Checking connectivity... done.
* (detached from v0.25.4)
  master

=> Source string already in /home/cristian/.zshrc
=> Close and reopen your terminal to start using nvm

sh to sh

sh -c "cat /home/cristian/extra/nvm/nvm/install.sh | sh; rm -rf "/home/cristian/.nvm";  exit;"
=> Downloading nvm from git to '/home/cristian/.nvm'
=> Cloning into '/home/cristian/.nvm'...
remote: Counting objects: 3693, done.
remote: Total 3693 (delta 0), reused 0 (delta 0), pack-reused 3693
Receiving objects: 100% (3693/3693), 827.00 KiB | 0 bytes/s, done.
Resolving deltas: 100% (2132/2132), done.
Checking connectivity... done.
* (detached from v0.25.4)
  master

=> Source string already in /home/cristian/.zshrc
=> Close and reopen your terminal to start using nvm

Piping to bash

zsh to bash

zsh -c "cat /home/cristian/extra/nvm/nvm/install.sh | bash; rm -rf "/home/cristian/.nvm";  exit;"
=> Downloading nvm from git to '/home/cristian/.nvm'
=> Cloning into '/home/cristian/.nvm'...
remote: Counting objects: 3693, done.
remote: Total 3693 (delta 0), reused 0 (delta 0), pack-reused 3693
Receiving objects: 100% (3693/3693), 827.00 KiB | 0 bytes/s, done.
Resolving deltas: 100% (2132/2132), done.
Checking connectivity... done.
* (detached from v0.25.4)
  master

=> Source string already in /home/cristian/.zshrc
=> Close and reopen your terminal to start using nvm

bash to bash

bash -c "cat /home/cristian/extra/nvm/nvm/install.sh | bash; rm -rf "/home/cristian/.nvm";  exit;"
=> Downloading nvm from git to '/home/cristian/.nvm'
=> Cloning into '/home/cristian/.nvm'...
remote: Counting objects: 3693, done.
remote: Total 3693 (delta 0), reused 0 (delta 0), pack-reused 3693
Receiving objects: 100% (3693/3693), 827.00 KiB | 0 bytes/s, done.
Resolving deltas: 100% (2132/2132), done.
Checking connectivity... done.
* (detached from v0.25.4)
  master

=> Source string already in /home/cristian/.zshrc
=> Close and reopen your terminal to start using nvm

ksh to bash

ksh -c "cat /home/cristian/extra/nvm/nvm/install.sh | bash; rm -rf "/home/cristian/.nvm";  exit;"
=> Downloading nvm from git to '/home/cristian/.nvm'
=> Cloning into '/home/cristian/.nvm'...
remote: Counting objects: 3693, done.
remote: Total 3693 (delta 0), reused 0 (delta 0), pack-reused 3693
Receiving objects: 100% (3693/3693), 827.00 KiB | 0 bytes/s, done.
Resolving deltas: 100% (2132/2132), done.
Checking connectivity... done.
* (detached from v0.25.4)
  master

=> Source string already in /home/cristian/.zshrc
=> Close and reopen your terminal to start using nvm

sh to bash

sh -c "cat /home/cristian/extra/nvm/nvm/install.sh | bash; rm -rf "/home/cristian/.nvm";  exit;"
=> Downloading nvm from git to '/home/cristian/.nvm'
=> Cloning into '/home/cristian/.nvm'...
remote: Counting objects: 3693, done.
remote: Total 3693 (delta 0), reused 0 (delta 0), pack-reused 3693
Receiving objects: 100% (3693/3693), 827.00 KiB | 651.00 KiB/s, done.
Resolving deltas: 100% (2132/2132), done.
Checking connectivity... done.
* (detached from v0.25.4)
  master

=> Source string already in /home/cristian/.zshrc
=> Close and reopen your terminal to start using nvm

@ljharb
Copy link
Member

ljharb commented Jun 12, 2015

Why are "bash to bash" and "ksh to bash" both doing "Source string already in /home/cristian/.zshrc"?

@CristianCantoro
Copy link
Contributor Author

@ljharb because the $SHELL env variable does not change if you launch the script with another shell. As I said above this is the intended behaviour otherwise when you do ... ./install.sh | bash it would use .bashrc which should not be the case.

@ljharb
Copy link
Member

ljharb commented Jun 12, 2015

Right but shouldn't "bash to bash", to be a useful test, have $SHELL set such that it's bash?

@CristianCantoro
Copy link
Contributor Author

Setting the $SHELL variable to /bin/bash with export SHELL="/bin/bash";

Setting $SHELL to bash

zsh to bash

echo "My shell is: $SHELL"; zsh -c "cat /home/cristian/extra/nvm/nvm/install.sh | bash; rm -rf "/home/cristian/.nvm";  exit;"
My shell is: /bin/bash
=> Downloading nvm from git to '/home/cristian/.nvm'
=> Cloning into '/home/cristian/.nvm'...
remote: Counting objects: 3693, done.
remote: Total 3693 (delta 0), reused 0 (delta 0), pack-reused 3693
Receiving objects: 100% (3693/3693), 827.00 KiB | 1.17 MiB/s, done.
Resolving deltas: 100% (2132/2132), done.
Checking connectivity... done.
* (detached from v0.25.4)
  master

=> Source string already in /home/cristian/.bashrc
=> Close and reopen your terminal to start using nvm

bash to bash

echo "My shell is: $SHELL"; bash -c "cat /home/cristian/extra/nvm/nvm/install.sh | bash; rm -rf "/home/cristian/.nvm";  exit;"
My shell is: /bin/bash
=> Downloading nvm from git to '/home/cristian/.nvm'
=> Cloning into '/home/cristian/.nvm'...
remote: Counting objects: 3693, done.
remote: Total 3693 (delta 0), reused 0 (delta 0), pack-reused 3693
Receiving objects: 100% (3693/3693), 827.00 KiB | 0 bytes/s, done.
Resolving deltas: 100% (2132/2132), done.
Checking connectivity... done.
* (detached from v0.25.4)
  master

=> Source string already in /home/cristian/.bashrc
=> Close and reopen your terminal to start using nvm

ksh to bash

echo "My shell is: $SHELL"; ksh -c "cat /home/cristian/extra/nvm/nvm/install.sh | bash; rm -rf "/home/cristian/.nvm";  exit;"
My shell is: /bin/bash
=> Downloading nvm from git to '/home/cristian/.nvm'
=> Cloning into '/home/cristian/.nvm'...
remote: Counting objects: 3693, done.
remote: Total 3693 (delta 0), reused 0 (delta 0), pack-reused 3693
Receiving objects: 100% (3693/3693), 827.00 KiB | 0 bytes/s, done.
Resolving deltas: 100% (2132/2132), done.
Checking connectivity... done.
* (detached from v0.25.4)
  master

=> Source string already in /home/cristian/.bashrc
=> Close and reopen your terminal to start using nvm

sh to bash

echo "My shell is: $SHELL"; sh -c "cat /home/cristian/extra/nvm/nvm/install.sh | bash; rm -rf "/home/cristian/.nvm";  exit;"
My shell is: /bin/bash
=> Downloading nvm from git to '/home/cristian/.nvm'
=> Cloning into '/home/cristian/.nvm'...
remote: Counting objects: 3693, done.
remote: Total 3693 (delta 0), reused 0 (delta 0), pack-reused 3693
Receiving objects: 100% (3693/3693), 827.00 KiB | 0 bytes/s, done.
Resolving deltas: 100% (2132/2132), done.
Checking connectivity... done.
* (detached from v0.25.4)
  master

=> Source string already in /home/cristian/.bashrc
=> Close and reopen your terminal to start using nvm

@ljharb
Copy link
Member

ljharb commented Jun 12, 2015

lol, now your zsh to bash test says "Source string already in /home/cristian/.bashrc"

@ljharb
Copy link
Member

ljharb commented Jun 12, 2015

Please do also add/modify the automated install_script tests for this new behavior.

@CristianCantoro
Copy link
Contributor Author

@ljharb it was already there exactly because when I tried the first install it added the line in .bashrc! (and yes, if you change your SHELL variable that's exactly what it should happen).

Anyhow, the important thing is the shell interpreter that is on the right hand side of the pipe (and so far I have tested it with sh/dash and bash because the left part basically just concatenates the output. (also, I was wrong above, even if you specify #!/bin/bash at the beginning of the script it gets executed with the shell interpreter that you specify on the right hand side.

@dfreeman
Copy link

dfreeman commented Jul 8, 2015

I'd love to see this change (or something similar) land. Is there anything I can do to help out in terms of verifying various shell combinations?

@ljharb
Copy link
Member

ljharb commented Jul 8, 2015

@dfreeman #765 (comment) and #765 (comment) are my latest comments. If @CristianCantoro is unavailable, unable, or unwilling to complete the PR, I'd say it's a great idea to cherry-pick his commits into your own branch, and complete it as a new PR! :-)

@dfreeman
Copy link

dfreeman commented Jul 8, 2015

Oops! That's what I get for skimming up and down the comment thread too quickly :)
Next time I've got a little time free, I'll see about pulling @CristianCantoro's initial work over into a fresh PR and wrapping it up (if he doesn't get to it in the meantime). Thanks!

@CristianCantoro
Copy link
Contributor Author

@dfreeman, @ljharb I am not 100% sure that the ksh install script is working 100%, I will double check that and see if I need to report an issue.

@ljharb
Copy link
Member

ljharb commented Jul 8, 2015

Thanks - I had to disable the ksh tests awhile back, so it's possible/likely there's an issue there.

@CristianCantoro CristianCantoro force-pushed the master branch 2 times, most recently from 0131cc0 to 935f5df Compare July 17, 2015 11:56
@CristianCantoro
Copy link
Contributor Author

Added the test and rebased the commit. Please note that I have also moved .profile higher in the priority for seaching dotfiles because this is a more sensible setting for people that have a $SHELL different from bash or zsh. The latter enjoy the advantage of having their shell detected directly and so for bash users the setting goes directly to .bashrc or .bash_profile. Analogously for zsh users the setting goes to .zshrc.

elif [ -f "$HOME/.profile" ]; then
echo "$HOME/.profile"

DETECTED_PROFILE=''
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind adding:

local DETECTED_PROFILE
local SHELLTYPE

and re-rebasing, to avoid global var pollution?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in bc91bc5.

@ljharb
Copy link
Member

ljharb commented Jul 18, 2015

I notice that when I start in bash, and then run zsh, $SHELL remains /bin/bash, but $0 is zsh.

Detecting the current shell is difficult, but I wonder if we could somehow use $0 (probably in the root of install.sh, not in a function) to more accurately detect the current shell?

@CristianCantoro
Copy link
Contributor Author

@ljharb it seems the intended behaviour to me. If you want to change your shell you should use chsh. I want to detect the user default (favourite?) shell, not necessarily the current shell.

@ljharb
Copy link
Member

ljharb commented Jul 18, 2015

Both for testing, and expectations, I'd expect that if i run the install script in X, it installs in X, even if that's not my default.

The current behavior is definitely attempting to detect the default, but I don't think that's quite as useful - since "install into the current shell" will match the default in most cases anyways.

@CristianCantoro
Copy link
Contributor Author

I am not sure of what would be the benefit of adding the configuration to a shell different from your default.
After all, after the installation, if you want to use nvm you still need to (either):

  • fire up a new shell (the new shell will be your default $SHELL)
  • source your .$SHELLrc file (works only if you are using your default shell (and only for bash and zsh, since ksh does not have a .kshrc file))
  • source .profile (works for every shell, if the configuration was added to .profile)
  • Execute the following command export NVM_DIR="$HOME/.nvm"; [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" (works for every shell)

the instructions also suggest to => Close and reopen your terminal to start using nvm

All in all it seems more useful to me that the configuration line gets added only to the default .$SHELLrc file (adding it in .profile would work for every shell, but I would rather have it added to a more specialized .$SHELLrc file if it is avaiable). If I am using bash as default and I am using zsh only for this session I may even have an empty .zshrc.
Finally, I also expect that people using a shell different from their default one know what they are doing. I do not see why (or how) one should expect that the configuration gets added to the current shell and then lose that configuration when they launch a new shell (or reboot, for example).

elif [ -f "$HOME/.profile" ]; then
echo "$HOME/.profile"

local DETECTED_PROFILE=''
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the local declaration, and the variable assignment, unfortunately need to be on separate lines to ensure compatibility with ksh. see lines 87-90 for an example.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 5f6f55f.

@ljharb
Copy link
Member

ljharb commented Jul 18, 2015

Fair point. When I run zsh from my default bash tho, it does source .zshrc, and thus loads nvm for me (because i'd manually added those lines previously). It'd be really convenient to do zsh && ./install.sh && dash && ./install.sh && bash && ./install.sh && sh && ./install.sh && ksh && ./install.sh etc to set up all my shells.

@CristianCantoro
Copy link
Contributor Author

@ljharb, yes, also on ubuntu .zshrc get loaded when launch zsh, and similarly .bashrc gets loaded whrn launching bash (.bash_profile does not get loaded, nor .profile (this, at least on Ubuntu))

I see what you mean for the installation. What about adding a different profile detection function if the configuration is already detected in the profile file?

@ljharb
Copy link
Member

ljharb commented Jul 18, 2015

I'd be totally fine with two modes of profile detection, "default" and "current". We can do that in a separate PR tho.

@CristianCantoro
Copy link
Contributor Author

Ok, so can we merge this PR? :)
Then I will look into implementing nvm_detect_default_profile and a nvm_detect_current_profile functions.

ljharb added a commit that referenced this pull request Jul 21, 2015
Detect shell type from $SHELL variable instead of .$SHELLrc files
@ljharb ljharb merged commit 1f679fc into nvm-sh:master Jul 21, 2015
@ljharb
Copy link
Member

ljharb commented Jul 21, 2015

Done, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
installing nvm: profile detection Issues with nvm's own install script, related to figuring out the right profile file.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants