I'm looking for a simple and reliable way to get the name of the current shell from inside a script or a sourced file (not from the command line). I would have expected to just do $(basename "$SHELL")
but if my login shell is zsh
and I have the following code in some_script.sh
this_shell=$( basename "$SHELL" )
echo "The Shell is $this_shell"
echo "The Shell is $0"
and I run it with bash some_script.sh
, it still lists zsh
instead of bash
even though the interpreter used is /bin/bash
. I'm not sure why shell designers chose to show the default shell instead of the current shell, but that seems to be what we're stuck with.
There are some other slightly similar questions (here and here), but their answers fall short in many ways.
- They often assume the user is trying to figure out what interactive shell they're currently using, but that's crazy. I know what shell I'm typing commands into--I need code that could be run anywhere to be able to determine what shell it is using.
- They often give several different things to try--again as though you're on the command line and can just fiddle around until you learn you're using bash--but I need one single thing that is reliable in all contexts.
- They often give things that are utterly useless from scripts, like
echo $0
. That fails as shown in the script above. (Yes it works in an interactive shell command line, but why would you ever not know what shell you're using?) - They sometimes give commands that (in my limited tests) include the correct information, like
ps -p $$
, but lack cross-platform, cross-shell compatible sed/awk commands to pipe it through to get just the shell name and ignore the other information that comes along for the ride. - They include things that will only work on a couple of shells, like
$BASH_VERSION
and$ZSH_VERSION
. I want to support as many shells as possible, such asfish
,csh
,tcsh
.
How do I reliably and accurately detect any current shell? I'm looking for something that will work across platforms, in scripts, and for as many shells as possible and reasonable1.
UPDATE: When I posted this question I expected that there was some facility built into the shells to give us this info, which appears to not be the case. Since it appears inevitable now to rely on something outside of the shells, I should make more explicit that I'm asking for a cross platform solution (which, though implied by my objections to other answers above, might be easy to miss if you don't read the question carefully).
Update 2 If anyone still believes this is a duplicate of the Linux-only question because Stéphane’s answer is not Linux-only, here are the differences between what I'm asking for and what he has provided. (Note that what he has written is ingenious, and I'm not knocking it, but it doesn't solve my problem.)
- I'm looking for something simple and reliable, that
- can be added to any script or function definition (that would be sourced by a
.zshrc
or.bash_profile
or whatever) to branch. - You cannot use his script as an outside utility that passes the interpreter name to the calling script/function, since it will always be interpreted by the default interpreter and return that. This makes it either difficult or impossible to use for my purposes. If it is possible, it is still very very difficult, and the solution to making it work is not given in the answer. Therefore he did not answer my question, therefore it is not a duplicate.
If you want to see something that will work, take a look at ShellDetective on GitHub. That may make it easier to see the differences between what is already present on SE, and what this question is looking for (and was in fact written in order to satisfy the needs of this question, which were unmet anywhere else).
(P.S. if you can't believe there's a use case for this, imagine functions that get sourced into .zshrc
, .bash_profile
, or .profile
depending on what server is being used and what shells it has available. They're sourced so they have no shebang line. They are most useful if they can work in any shell, but sometimes they have to know which shell they're in to know how to behave.)
1 I'm not concerned with "shells" that are not shells in any traditional sense of the word. I'm not concerned with some shell that some guy wrote for himself. I'm only concerned with real shells that actually occur in the wild, and which someone might conceivably have to use when logging into some server on which they cannot just install whatever shells they want.
sh -c "…"
, and then do the bulk of the work in POSIX shell syntax. – G-Man Says 'Reinstate Monica' Aug 07 '15 at 06:02readlink /proc/$$/exe
should to the job fairly consistently. – DopeGhoti Aug 07 '15 at 17:35cp /bin/csh /tmp/fish; /tmp/fish /path/to/script & rm /tmp/fish
? – Gilles 'SO- stop being evil' Aug 07 '15 at 22:15fish
and use it to run your script, do you wantfish
orcsh
? – Gilles 'SO- stop being evil' Aug 08 '15 at 07:42sh
are really handled bybash
? In the latter case I guess it depends on how wellbash
mimicssh
: will it fail on things thatsh
would have failed on? – iconoclast Aug 08 '15 at 14:41readlink /proc/$$/exe
(by Patrick). (Note that DopeGhoti gave the same answer in a comment yesterday.) Most up-voted answer: a 35-line, 1750-character Emperor’s cloak that must be beautiful, because I can’t see it. (Seriously, it’s by Stéphane Chazelas, so it’s probably super-intelligent.) – G-Man Says 'Reinstate Monica' Aug 08 '15 at 22:23readlink /proc/$$/exe
notion when DopeGhoti proposed it. Have you looked at Stéphane’s answer? (I don't know whether it will work for you, because I don't understand it, myself, but Stéphane has an excellent track record.) – G-Man Says 'Reinstate Monica' Aug 09 '15 at 19:55zsh
on my system asbash
. I have other qualms about it—though whoever wrote it seems to be a genius—but that's the biggest one. – iconoclast Aug 09 '15 at 20:06