Get the exit code for a command in Bash and KornShell (ksh)

Below is the fixed code:

#!/bin/ksh
safeRunCommand() {
  typeset cmnd="$*"
  typeset ret_code

  echo cmnd=$cmnd
  eval $cmnd
  ret_code=$?
  if [ $ret_code != 0 ]; then
    printf "Error: [%d] when executing command: '$cmnd'" $ret_code
    exit $ret_code
  fi
}

command="ls -l | grep p"
safeRunCommand "$command"

Now if you look into this code, the few things that I changed are:

  • use of typeset is not necessary, but it is a good practice. It makes cmnd and ret_code local to safeRunCommand
  • use of ret_code is not necessary, but it is a good practice to store the return code in some variable (and store it ASAP), so that you can use it later like I did in printf "Error: [%d] when executing command: '$command'" $ret_code
  • pass the command with quotes surrounding the command like safeRunCommand "$command". If you don’t then cmnd will get only the value ls and not ls -l. And it is even more important if your command contains pipes.
  • you can use typeset cmnd="$*" instead of typeset cmnd="$1" if you want to keep the spaces. You can try with both depending upon how complex is your command argument.
  • 'eval' is used to evaluate so that a command containing pipes can work fine

Note: Do remember some commands give 1 as the return code even though there isn't any error like grep. If grep found something it will return 0, else 1.

I had tested with KornShell and Bash. And it worked fine. Let me know if you face issues running this.


Try

safeRunCommand() {
   "$@"

   if [ $? != 0 ]; then
      printf "Error when executing command: '$1'"
      exit $ERROR_CODE
   fi
}

It should be $cmd instead of $($cmd). It works fine with that on my box.

Your script works only for one-word commands, like ls. It will not work for "ls cpp". For this to work, replace cmd="$1"; $cmd with "$@". And, do not run your script as command="some cmd"; safeRun command. Run it as safeRun some cmd.

Also, when you have to debug your Bash scripts, execute with '-x' flag. [bash -x s.sh].