可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
How can I tell what type my shell is? ie, whether it's traditional sh, bash, ksh, csh, zsh etc.
Note that checking $SHELL
or $0
won't work because $SHELL
isn't set by all shells, so if you start in one shell and then start a different one you may still have the old $SHELL
.
$0
only tells you where the shell binary is, but doesn't tell you whether /bin/sh
is a real Bourne shell or bash.
I presume that the answer will be "try some features and see what breaks", so if anyone can point me at a script that does that, that'd be great.
回答1:
This is what I use in my .profile
:
# .profile is sourced at login by sh and ksh. The zsh sources .zshrc and
# bash sources .bashrc. To get the same behaviour from zsh and bash as well
# I suggest "cd; ln -s .profile .zshrc; ln -s .profile .bashrc".
# Determine what (Bourne compatible) shell we are running under. Put the result
# in $PROFILE_SHELL (not $SHELL) so further code can depend on the shell type.
if test -n "$ZSH_VERSION"; then
PROFILE_SHELL=zsh
elif test -n "$BASH_VERSION"; then
PROFILE_SHELL=bash
elif test -n "$KSH_VERSION"; then
PROFILE_SHELL=ksh
elif test -n "$FCEDIT"; then
PROFILE_SHELL=ksh
elif test -n "$PS3"; then
PROFILE_SHELL=unknown
else
PROFILE_SHELL=sh
fi
It does not make fine distinctions between ksh88, ksh95, pdksh or mksh etc., but in more than ten years it has proven to work for me as designed on all the systems I were at home on (BSD, SunOS, Solaris, Linux, Unicos, HP-UX, AIX, IRIX, MicroStation, Cygwin.)
I don't see the need to check for csh in .profile
, as csh sources other files at startup.
Any script you write does not need to check for csh vs Bourne-heritage because you explicitly name the interpreter in the shebang line.
回答2:
Try to locate the shell path using the current shell PID:
ps -p $$
It should work at least with sh, bash and ksh.
回答3:
If the reason you're asking is to try to write portable shell code, then spotting the shell type, and switching based on it, is an unreliable strategy. There's just too much variation possible.
Depending on what you're doing here, you might want to look at the relevant part of the autoconf documentation. That includes an interesting (and in some respects quite dismal) zoology of different shell aberrations.
For the goal of portable code, this section should be very helpful. If you do need to spot shell variants, then there might be some code buried in autoconf (or at least in one of the ./configure
scripts it generates) which will help with the sniffing.
回答4:
You can use something like this:
shell=`cat /proc/$$/cmdline`;
回答5:
Oh, I had this problem. :D
There is a quick hack, use ps -p $$
command to list the process with PID of the current running process -- which is your SHELL. This returns a string table structure, if you want, you can AWK, or SED the shell out...
回答6:
It's old thread but...
In GNU environment You can sh --help
and get something like
BusyBox v1.23.2 (2015-04-24 15:46:01 GMT) multi-call binary.
Usage: sh [-/+OPTIONS] [-/+o OPT]... [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS]]
Unix shell interpreter
So, the first line is shell type =)
回答7:
The system shell is the thing you see when you open up a fresh terminal window which is not set to something other than bash (assuming this is your default SHELL
).
echo $SHELL
Generally, you can find out all the constants defined by running
set
If the output is a lot of stuff then run
set | less
so you can scroll it from the top of the command line or
set > set.txt
To save the output to a file.
Invoking a different interactive shell to bash in your terminal does not mean that your system shell gets changed to something else i.e. your system shell is set to bash although you invoke a csh shell from a bash shell just that one session.
The above means that typing /bin/csh
or /bin/python
in bash or whatever does not set the system shell to the shell you invoked, at all.
If you really want to see the SHELL constant change then you need to set it to something else. If successful you should see the new shell whenever you open a fresh terminal...