I'm trying to use the tput command in a bash script if statement but for some reason it's behaving unexpectedly. When running the command and then checking the exit code only in the if statement things work correctly, however, when running the command in the if statement directly things no longer work. Here's a simple script to illustrate my issue:


tput setaf 1
if [ $? ]
  echo "first if works"

if tput setaf 1
  echo "second if works"

Running this script only prints "first if works". Shouldn't both of these if statements work since they are equivalent? Am I missing something? BTW, this is running on FreeBSD in case that matters.

1 Answer 1


These statements are not equivalent.

The first is checking whether $? is a non-empty string; it always will be, so the body of the first if will always run. [string] is

True if the string string is not the null string; otherwise, false.

The second is checking whether tput setaf 1 succeeded, or alternatively, whether its exit status (and therefore $?) is zero. The body of the second if will only run when the tput command succeeds. It is broadly equivalent to

tput setaf 1
if [ $? -eq 0 ]

The result you're describing indicates that tput setaf 1 is exiting with some non-zero code (for example, 1). "1" is a non-empty string, but it isn't zero. tput setaf 1 ; echo $? would show you what the actual code is, which you could then investigate further.

  • $? (unquoted) will always be a non-empty string unless IFS contains digits... :-)
    – Kusalananda
    Jul 22, 2018 at 6:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .