The scenario is that users are asked to source a script file:
$ source envsetup.sh
This script file may use bash only feature so we have detect the running shell is bash or not.
For other shells that share common syntax with bash, for example, sh, zsh, ksh, I'd like to report a warning.
What is the most reliable way to detect the current shell across Linux, Cygwin, OS X?
What I know is $BASH, but I am wondering the chances it could fail.
Using the lsof Command The first column COMMAND in the output shows that the running shell is bash.
Bash commands to check running process: pgrep command – Looks through the currently running bash processes on Linux and lists the process IDs (PID) on screen. pidof command – Find the process ID of a running program on Linux or Unix-like system.
Check Bash version from within shell script#!/bin/bash echo "Checking for Bash version...." echo "The Bash version is $BASH_VERSION !" Once ready, make the file executable and run the script: $ chmod +x check-bash-version.sh $ ./check-bash-version.sh Checking for Bash version.... The Bash version is 4.4.
Using Bash To Check Script Syntax. The Bash -n (noexec) option tells Bash to read a script and check it for syntactical errors, without running the script.
There are a bunch of environment variables that you can look at but many of them will not detect if a different shell is spawned from bash. Consider the following:
bash$ echo "SHELL: $SHELL, shell: $shell, ARGV[0]: $0, PS1: $PS1, prompt: $prompt"
SHELL: /bin/bash, shell: , ARGV[0]: -bash, PS1: bash$ , prompt:
bash$ csh
[lorien:~] daveshawley% echo "SHELL: $SHELL, shell: $shell, \$0: $0, PS1: $PS1, prompt: $prompt"
SHELL: /bin/bash, shell: /bin/tcsh, ARGV[0]: csh, PS1: bash$ , prompt: [%m:%c3] %n%#
[lorien:~] daveshawley% bash -r
bash$ echo "SHELL: $SHELL, shell: $shell, ARGV[0]: $0, PS1: $PS1, prompt: $prompt"
SHELL: /bin/bash, shell: , ARGV[0]: sh, PS1: bash$ , prompt:
bash$ zsh
% echo "SHELL: $SHELL, shell: $shell, ARGV[0]: $0, PS1: $PS1, prompt: $prompt"
SHELL: /bin/bash, shell: , ARGV[0]: zsh, PS1: % , prompt: %
% ksh
$ echo "SHELL: $SHELL, shell: $shell, ARGV[0]: $0, PS1: $PS1, prompt: $prompt"
SHELL: /bin/bash, shell: , ARGV[0]: ksh, PS1: bash$ , prompt:
There are a number of variables specific to the various shells except that they have a habit of being inherited by sub-shells which is where the environment thing really breaks. The only thing that almost works is ps -o command -p $$
. This technically gives you the command name that the shell is running as. In most cases this will work... since applications are started with some variant of the exec
system call and it allows for the name of the command and the executable to differ, it is possible for this to fail as well. Consider:
bash$ exec -a "-csh" bash
bash$ echo "$0, $SHELL, $BASH"
-csh, /bin/bash, /bin/bash
bash$ ps -o command -p $$
COMMAND
-csh
bash$
Another trick is to use lsof -p $$ | awk '(NR==2) {print $1}'
. This is probably as close as you can get if you are lucky enough to have lsof
handy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With