I have this bash function which I am trying to use to install a command line tool if it's not already in the PATH:


  if ! type -f ncf &> /dev/null || ! which ncf &> /dev/null; then

       echo "Installing NPM package '@oresoftware/ncf' globally...";

       npm i -s -g '@oresoftware/ncf' || {
         echo -e "Could not install NPM package '@oresoftware/ncf' globally." >&2
         echo -e "Please check your permissions to install global NPM packages." >&2
         return 1;


  command ncf $@;

I have a couple of questions - is type -f ncf and which ncf redundant? Right now, I am checking to see if either of them exits with non-zero - if I either one does, I reinstall (at least that's what I think the code is doing).

My other question is - will &> work for bash versions older than 4, or other shells like sh, ksh, zsh, etc? Is there another construct I should use that's more cross platform than &>?

  • Would it not make sense to explicitly set the PATH in the script so that it includes the directory where the program ought to be found? If that directory is not in PATH, you won't be able to start it no matter how much you install it. Also, quote $@, and you don't need ; at the end of statements if there is no other statement afterwards on the same line. – Kusalananda Jun 24 '18 at 12:23
  • @Kusalananda thanks, I have never figured out if I should quote "$@" or not. Why quote it? – Alexander Mills Jun 24 '18 at 19:13
  • 2
    If you don't quote $@, the shell will perform word splitting and filename globbing on its individual elements. You should always quote all expansions (there only a couple of cases where you don't have to, but it's a good rule of thumb to do it everywhere). – Kusalananda Jun 24 '18 at 20:33

which is redundant with type, except when it does the wrong thing altogether. Don't use which ever (except in ksh or zsh). Don't use type -f in portable sh, either: that's a ksh/bash extension. Just use plain type. If you want to look for an external command despite the presence of a function by the same name, you can use (unset -f ncf; type ncf).

To redirect the output away, use >/dev/null 2>&1. This can be abbreviated to &>/dev/null in ksh, bash and zsh, but not in plain sh.

  if ! type -f ncf >/dev/null 2>/dev/null; then …
| improve this answer | |
  • 1
    or ... >/dev/null 2>&1 will be portable too, won't it? – glenn jackman Jun 24 '18 at 10:33
  • @glennjackman Yes, that works too. It's actually closer to &>/dev/null since it only opens the file once, but for /dev/null that doesn't matter. – Gilles 'SO- stop being evil' Jun 24 '18 at 10:45
  • unset -f ncf right, not unset ncf? – Alexander Mills Jun 24 '18 at 19:10
  • What about using command -v ncf, is that better than type -f? – Alexander Mills Jun 24 '18 at 19:13
  • Because I am using command ncf to execute it, I would guess it makes the most sense to check if it doesn't exist by using command -v ncf? – Alexander Mills Jun 24 '18 at 19:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.