Search code examples
bashio-redirectionexit-code

Why doesn't testing exit status work when output is redirected?


I have been testing bash and found the following code:

#!/bin/bash

[[ `which pacman` ]] && echo pacman
[[ `which apt-get` ]] && echo apt-get

It will test what package manager is installed and echo it.

On some systems, a failed which command prints the error to stderr. I want to suppress all output from the which command.

So I came up with the following code:

#!/bin/bash

[[ `which pacman >/dev/null 2>&1` ]] && echo pacman
[[ `which apt-get >/dev/null 2>&1` ]] && echo apt-get

But this doesn't output anything. When I run each command on the command line like this:

which pacman >/dev/null 2>&1 && echo $?

On a system with pacman, it prints 0 which it should. The && also proves that the previous command succeeded.

So why doesn't the redirection code work like it does on the command line? What can I add to the script to make it work?

This is really confusing to me, as I have never had this type of problem before. Usually, any command that works on the command line should also work in a bash script, shouldn't it?


Solution

  • [[ ... ]] without a specified test runs [[ -n ... ]]. In this case, it tests whether the captured output is non-empty. But if you redirect everything to /dev/null, the output is indeed empty!

    You don't need to capture the output. which should already return a non-zero status when it cannot find the file to execute.

    which pacman &> /dev/null && echo pacman