Guidance required in .profile

Not every server I use has bash so I wanted to add an option to check if bash exists. This is what I tried. This is the error message it gives "-bash: [: missing `]'". It works before I add the and option.

if [ -s ~/.bashrc && -s /usr/bin/bash ]; then
    echo hi
    source ~/.bashrc;
fi

The test ( or [ ) command does not like the && operator. Use (deprecated) -a instead, or use [[ ... ]] .

Thank you. Worked perfectly.

One could also portably use:

if [ -s ~/.bashrc ] && [ -s /usr/bin/bash ]; then

Although && isn't a test (or [ ... ] ) utility operator, it is a shell operator.

The problem with the above is, if bash exists but you are not running bash, your shell will baulk at an instruction in the .bashrc file.

Try something like this at the end of your .profile:

if [ -z "$BASH_VERSION" ] 
then
   if [ -x /usr/bin/bash ]
   then
      SHELL=/usr/bin/bash
      export SHELL
      exec $SHELL
   elif [ -x /bin/bash ]
   then
      SHELL=/bin/bash
      export SHELL
      exec $SHELL
   fi
fi

This way, if bash exists, but is not your login shell, your shell will switch to bash at the end of the .profile. You can also add a test for bash being in /usr/local/bin.

Andrew

Bash is thankfully my default shell. I was trying to solve the problem of when bash does not exist. Ksh is the system default but I changed my personal default to bash. How would I fall back to ksh if bash does not exist?

Do older systems not like this? Is that what you were saying with portably?

if [[ -s ~/.bashrc && /usr/bin/bash ]]; then
    #echo hi
    source ~/.bashrc;
fi

So basically you are asking, "is my login shell bash or ksh?" And if there is no bash on your system it will be ksh, because that is the default, else you will have changed it by the time your regular .profile has been installed. Your SHELL variable will be set to your login shell and bash, from version 2 at least, will have the BASH_VERSION variable. So, either:

[ -n "$BASH_VERSION" ] && . ./.bashrc

or

case "$SHELL" in
*bash) . ./.bashrc ;;
*ksh) . ./.kshrc ;;
esac

should do it.

POSIX shell and older shells don't support the double square bracket operator; and the single square bracket operator doesn't support the && and || operators. Personally, I think it's more readable to keep one expression per square bracket operator, whether it is single or double.

Andrew

1 Like