-1

I'm writing a shell script, and I need to check for some dependencies being installed before executing anything. I found I can use which <package> to see if it is installed or not. The problem is that when that dependency is not found, it throws the following error into console's output:

which: no abc in (/home/pace/.emacs.d/bin:/usr/local/bin:/home/pace/.emacs.d/bin:/usr/local/bin:/home/pace/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:...)

I want to avoid having such output, as I already have error messages shown when something fails. How can I avoid which from writing anything?

function is_installed() {
  if [[ ! $(which $1) ]]
  then
    echo "[ERROR]: $1 $2"
    exit 1
  fi
}
  • 1
    Or [How can I check if a program exists from a Bash script?](https://stackoverflow.com/q/592620/3266847) – Benjamin W. May 30 '21 at 16:58
  • None of those questions answer mine. I want to avoid the error thrown when nothing is found and through my own error trace, I already know how to find the path. I would appreciate if you remove the negative feedback of the question, as it is not a duplicate one. – Pablo Acereda May 30 '21 at 21:34
  • `which` continues to be the wrong solution unless you specifically pin to a platform which you know exactly `which which` you have. The portable POSIX solution is `command` (or possibly `type`). See https://unix.stackexchange.com/questions/85249/why-not-use-which-what-to-use-then – tripleee May 31 '21 at 05:26

1 Answers1

1

Well, there might be better ways to do what you're trying to do (I'm not certain of the "best" way), but you can redirect stderr and stdout to hide the results from the output:

function is_installed() {
  if [[ ! $(which $1 > /dev/null 2>&1 ) ]]
  then
    echo "[ERROR]: $1 $2"
    exit 1
  fi
}

(recent versions of bash support using >& /dev/null too to do both at once, but the above is slightly more portable)

EDIT -- try this instead

function is_installed() {
  which $1 > /dev/null 2>&1
  if [ $? = 1 ] ; then
    echo "[ERROR]: $1 $2"
    exit 1
  fi
}
Wes Hardaker
  • 21,735
  • 2
  • 38
  • 69
  • If I do that, the conditional statement stops working and doesn't identify any installed package anymore. – Pablo Acereda May 30 '21 at 16:53
  • replaced the code above in an edit for you. – Wes Hardaker May 30 '21 at 16:57
  • Doesn't work either, due to the `set -euo pipefail` header, the script stops abruptly without showing any error message. – Pablo Acereda May 30 '21 at 21:28
  • So why are you setting that then? If you have that set, then yes you will run into issues. But you need the exit status from the `which` and if you have those settings, then you won't be able to get it. Why not set pipefile, etc, after you test for requirements? – Wes Hardaker May 30 '21 at 22:49