In my .profile
, I use the following code to ensure that Bash-related aliases and functions are only sourced if the login shell actually is Bash:
# If the current (login) shell is Bash, then
if [ "${BASH_VERSION:-}" ]; then
# source ~/.bashrc if it exists.
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi
I’m currently in the process of putting my shell configuration files, scripts and functions under version control. I’ve also recently started the process of removing casual Bashisms from shell scripts that don’t benefit from Bash-specific features, e.g., replacing function funcname()
with funcname()
.
For my shell files repository, I’ve configured a pre-commit hook that runs the checkbashisms
utility from Debian’s devscripts package on each sh
file in the repository to ensure that I don’t inadvertently introduce Bash-specific syntax. However, this raises an error for my .profile
:
possible bashism in .profile line 51 ($BASH_SOMETHING):
if [ "${BASH_VERSION:-}" ]; then
I was wondering if there was a way to check which shell is running that wouldn’t trigger a warning in checkbashisms
.
I checked the list of shell-related variables listed by POSIX in the hope that one of them could used to show the current shell. I’ve also looked at the variables set in an interactive Dash shell but, again, failed to find a suitable candidate.
At the moment, I’ve excluded .profile
from being processed by checkbashisms
; it’s a small file so it’s not hard to check it manually. However, having researched the issue, I’d still like to know if there is a POSIX compliant method to determine which shell is running (or at least a way that doesn’t cause checkbashisms
to fail).
Further background/clarification
One of the reasons I’m putting my shell configuration files under version control is to configure my environment on all the systems I currently log in to on a regular basis: Cygwin, Ubuntu and CentOS (both 5 and 7, using Active Directory for user authentication). I most often log on via X Windows / desktop environments and SSH for remote hosts. However, I’d like this to be future proof and have the least reliance on system dependencies and other tools as possible.
I’ve been using checkbashisms
as a simple, automated sanity check for the syntax of my shell-related files. It’s not a perfect tool, e.g., I’ve already applied a patch to it so that it doesn’t complain about the use of command -v
in my scripts. While researching, I’ve learned that the program’s actual purpose is to ensure compliance with Debian policy which, as I understand it, is based on POSIX 2004 rather than 2008 (or its 2013 revision).
Best Answer
Your
code is completely POSIX conformant and the best way to check that you're currently running
bash
. Of course the$BASH_VERSION
variable is bash-specific, but that's specifically why you're using it! To check that you're runningbash
!Note that
$BASH_VERSION
will be set whetherbash
is invoked asbash
orsh
. Once you've asserted that you're runningbash
, you can use[ -o posix ]
as an indicator that the shell was invoked assh
(though that option is also set when POSIXLY_CORRECT is in the environment orbash
is called with-o posix
, or with SHELLOPTS=posix in the environment. But in all those cases,bash
will behave as if called assh
).Another variable you could use instead of
$BASH_VERSION
and thatcheckbashism
doesn't seem to complain about unless passed the-x
option is$BASH
. That is also specific tobash
so one you should also be able to use to determine whether you're runningbash
or not.I'd also argue it's not really a proper use of
checkbashisms
.checkbashisms
is a tool to help you write portablesh
scripts (as per thesh
specification in the Debian policy, a superset of POSIX), it helps identify non-standard syntax introduced by people writing scripts on systems wheresh
is a symlink tobash
.A
.profile
is interpreted by different shells, many of which are not POSIX compliant. Generally, you don't usesh
as your login shell, but shells likezsh
,fish
orbash
with more advanced interactive features.bash
andzsh
, when not called assh
and when their respective profile session file (.bash_profile
,.zprofile
) are not POSIX conformant (especiallyzsh
) but still read.profile
.So it's not POSIX syntax you want for
.profile
but a syntax that is compatible with POSIX (forsh
),bash
andzsh
if you're ever to use those shells (possibly even Bourne as the Bourne shell also reads.profile
but is not commonly found on Linux-based systems).checkbashisms
would definitely help you find out bashisms but may not point out POSIX syntax that is not compatible withzsh
orbash
.Here, if you want to use
bash
-specific code (like the work around of thatbash
bug whereby it doesn't read~/.bashrc
in interactive login shells), a better approach would be to have~/.bash_profile
do that (before or after sourcing~/.profile
where you put your common session initialisations).