0

is it possible to pass conditions that are checked in if clauses (https://tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_01.html) as arguments to a function? The following does not work.

print_message_if_condition_holds() {
  local CONDITION="$1"
  local MESSAGE="$2"

  if $CONDITION; then
    echo "$MESSAGE"
  fi
}

print_message_if_condition_holds [ 0 -eq 0 ] "Success"

can it be done with somewhat different syntax?

1 Answers1

3

I'm not sure how advisable it is, but you could do it by treating each token as a separate positional parameter. Since conditionals may take varying numbers of tokens ([ -z str ], [ str ], [ n -lt m ] and so on) you can't hard-code for the parameters - but provided there is only a single messaage then you could swap the order and do

print_message_if_condition_holds() {
  local message=$1
  shift
  local condition=("$@")

  if "${condition[@]}"; then
    echo "$message"
  fi
}

print_message_if_condition_holds "Success" [ 0 -eq 0 ] 

Somewhat related:

steeldriver
  • 78,509
  • 12
  • 109
  • 152
  • not bad already, this doesn't seem to work for 'or' conditions though, such as `[ 1 -eq 0 ] || [ 0 -eq 0 ]` – matthias_buehlmann Feb 20 '21 at 23:56
  • @matthias_buehlmann that's true yes - in general, everything after the first *control operator* will be considered part of a separate *simple command* – steeldriver Feb 21 '21 at 00:03
  • You could try composing conditions like `COND="( $a -eq $b -o $c -ne $d ) -a -n $e"`, then pass that string to the `test` or `[` command such as `if [ "$COND" ]`. – berndbausch Feb 21 '21 at 02:03
  • Or, pass the arguments to `[` to the function: `print_message_if_condition_holds() { local msg=$1; shift; [ "$@" ] && echo "$msg"; }` -- then `print_message_if_condition_holds "Success" "$a" -eq "$b"` – glenn jackman Feb 21 '21 at 18:06
  • @glennjackman yes indeed that sounds like a more robust solution – steeldriver Feb 21 '21 at 20:14
  • What am I missing?  How is glenn's answer more robust than steeldriver's original answer? The only benefit I see is that glenn's answer saves you the bother of typing `[` and `]` — but it prevents you from doing things like `print_message_if_condition_holds "Files are identical" cmp -s file1 file2`. – Scott - Слава Україні Apr 01 '21 at 00:24