Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HOWTO: Detect bash from shell script

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.

like image 918
Kan-Ru Chen Avatar asked Jul 08 '10 00:07

Kan-Ru Chen


People also ask

How do I know if my shell is bash?

Using the lsof Command The first column COMMAND in the output shows that the running shell is bash.

How do I know if bash script is running?

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.

How do I find bash commands?

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.

What is the syntax to check bash shell script?

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.


1 Answers

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.

like image 173
D.Shawley Avatar answered Sep 16 '22 16:09

D.Shawley