not entering if condition when using a function

2019-09-09 15:28发布

问题:

#!/bin/bash

function func_name {

arg1=$1; arg2=$2; 

if [[ "${arg1}" == "abcd" ]]; then
    echo enterd abcd condition
else
    echo entered else
fi

}

export -f func_name

find . -name "*" -type d -exec bash -c '( cd {} &&

func_name;

)' bash $1 $2 {} \;

Trying to run a function having if condition as a subshell inside find statement. It just enters else part. Why?

回答1:

It's not clear what arguments should be passed where, but your current attempt is certainly wrong. You aren't passing any arguments to func_name when you are calling it, so "$arg1" is expanding to the empty string. I suspect you want something like

find . -name "*" -type d -exec bash -c 'cd "$1" && func_name "$2" "$3"' {} "$1" "$2" \;

Here, func_name is explicitly given the arguments passed to the original script. You don't need the subshell in the argument to -c, since the entire command is already run in a separate process.

If you are using bash 4 or later, you probably don't actually need to use find.

shopt -s globstar
for d in **/*/; do
    pushd "$d"
    func_name "$1" "$2"
    pops
done


回答2:

Variables inside a function block are only evaluated when the function is called. If you want to bind some variables at function declaration time, use eval, or a pair of global variables.

#!/bin/bash

_private_foo=$1
_private_bar=$2

func_name {
  if [[ "$_private_foo" == "abcd" ]]; then
    echo entered abcd condition
  else
    echo entered else
  fi
}

If subsequent code never changes the global variables _private_foo and _private_bar, the function will work as if the initial global values of $1 and $2 were interpolated into the function definition, without the myriad complications and perils of eval.

If you need the function to work in a subshell, you'll need to also export the globals, or somehow otherwise pass them in, as pointed out by @chepner.



标签: bash shell