Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

passing multiple bash commands to a function

I want to pass in multiple commands using a && operator into a single function call. Each command could have a different number of parameters so I’m using the $@ to capture all of them. With a single command, the function below works fine.

function try_log () {
     $@ \
         && echo "PASS!"
         || echo "FAIL!"
}

$ try_log touch foo bar
  PASS!
$ try_log rm foo bar
  PASS!
$ try_log rm foo bar
rm: cannot remove 'foo': No such file or directory
rm: cannot remove 'bar': No such file or directory
  FAIL!

I now want to add support for an && operatoron the input command. The intent is to run the entire command then display a PASS or FAIL at the end. I’ve tried the following without success.

try_log ls && ls # runs the send ls after the first completes
foo bar
  PASS!
foo bar

try_log 'ls && ls'
ls: cannot access '&&': No such file or directory
ls: cannot access 'ls': No such file or directory
  FAIL!

$ try_log `ls && ls`
foo: command not found
  FAIL!


MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

First, your function does not work fine. You need to quote $@ to handle arbitrary arguments, and you should just use a regular if statement rather than trying to simulate a conditional expression using && and ||.

try_log () {
     if "$@"; then echo "$PASS!"; else echo "FAIL!"; fi
}

The problem is that this only handles simple commands, consisting of the name of a command and its arguments. It does not handle pipelines, compound commands like [[, if, etc, or command lists like a && b. The only real solution is to pass the command as a single string and let try_log use eval to parse and execute it.

try_log () {
     if eval "$1"; then echo "$PASS!"; else echo "FAIL!"; fi
}

try_log "ls && ls"

(This is not an "evil" use of eval, because you are using it exactly what it is intended for: executing arbitrary code. Just make sure you, and not an untrusted user, are providing the arbitrary code.)

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading