1

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:

ncf(){

  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;
       }

  fi

  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 &>?

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
Alexander Mills
  • 9,330
  • 19
  • 95
  • 180
  • 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

1 Answers1

1

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 …
Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175