Alessandro Lorusso
Alessandro Lorusso

Reputation: 357

What does an if statement with only a variable evaluate to in bash?

I'm learning about bash --login and saw that the commands in /etc/profile are executed first. In that file:

# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
# and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).

if [ "`id -u`" -eq 0 ]; then
  PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
else
  PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games"
fi
export PATH

if [ "$PS1" ]; then
  if [ "$BASH" ] && [ "$BASH" != "/bin/sh" ]; then
    # The file bash.bashrc already sets the default PS1.
    # PS1='\h:\w\$ '
    if [ -f /etc/bash.bashrc ]; then
      . /etc/bash.bashrc
    fi
  else
    if [ "`id -u`" -eq 0 ]; then
      PS1='# '
    else
      PS1='$ '
    fi
  fi
fi

if [ -d /etc/profile.d ]; then
  for i in /etc/profile.d/*.sh; do
    if [ -r $i ]; then
      . $i
    fi
  done
  unset i
fi

Now, I admittedly have a limited understanding of control flow in bash but from my understanding, most of the time what I see put in the if statement is some kind of conditional statement, whether it is [-a FILENAME] to check if a file exists or a comparison between strings, usually it evaluates to something.

In the file, two if statements confuse me:

if [ "$PS1" ]; and if[ "$BASH" ]

I know that PS1 is a variable for the primary prompt, but that's all that's in the if statement. It's not using -a to check existence or comparing it to something else. My educated guess is that simply putting a variable will evaluate to true if it exists.

My question is what do these if statements evaluate to and why?

Upvotes: 2

Views: 1860

Answers (2)

agc
agc

Reputation: 8406

The code if [ "$PS1" ]; and if [ "$BASH" ] test if the strings "$PS1" and "$BASH" are empty, and do something if they are; and since the if [ "$BASH" ] test has a matching else it also does something if $BASH is empty.

The long form of the statement might be clearer, but the following are all equivalent:

test -n "$PS1"   # returns an exit code of `0` if `$PS1` is not empty, or `1` if not.

Shorter:

test "$PS1" 

Shorter:

[ -n "$PS1" ] 

Shortest:

[ "$PS1" ] 

Upvotes: 1

John1024
John1024

Reputation: 113814

[ "$var" ] returns true if the length of $var is non-zero. If var is either unset or empty, it returns false.

This is useful:

  • [ "$PS1" ] will evaluate to true only for interactive shells.

  • [ "$BASH" ] will evaluate to true only if the shell is bash (as opposed to dash, ksh, or zsh, etc.).

Examples

Only one of the following evaluates to true:

$ unset x; [ "$x" ] && echo yes
$ x=""; [ "$x" ] && echo yes
$ x="a"; [ "$x" ] && echo yes
yes

Documentation

This is documented both in man bash and, as Glenn Jackman notes, in bash's interactive help system. For information on the [ command, type:

$ help [
[: [ arg... ]
    Evaluate conditional expression.

    This is a synonym for the "test" builtin, but the last argument must
    be a literal `]', to match the opening `['.

The above refers you to test. Run help test for much more detail:

$ help test | less

Scroll through that documentation and one finds:

  STRING      True if string is not empty.

Upvotes: 3

Related Questions