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
  • 81,074
  • 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