1

This was my starting point: shell script - Executing user defined function in a find -exec call - Unix & Linux Stack Exchange

But I need to choose between 2 different versions of the function, based on an argument passed to the containing script. I have a working version, but it has a lot of duplicate code. I'm trying to implement it better, but I can't quite figure out how to do that in this context.

Here's the core code:

cmd_force() {
  git fetch; 
  git reset --hard HEAD; 
  git merge '@{u}:HEAD';
  newpkg=$(makepkg --packagelist);
  makepkg -Ccr; 
  repoctl add -m $newpkg;
}

cmd_nice() {
  git pull;
  newpkg=$(makepkg --packagelist);
  makepkg -Ccr; 
  repoctl add -m $newpkg;
}

if [[ $force == "y" ]] ; then
  export -f cmd_force
  find . -mindepth 2 -maxdepth 2 -name PKGBUILD -execdir bash -c 'cmd_force' bash {} \;
else
  echo "Call this with the -f option in case of: error: Your local changes to ... files would be overwritten by merge"
  export -f cmd_nice
  find . -mindepth 2 -maxdepth 2 -name PKGBUILD -execdir bash -c 'cmd_nice' bash {} \;
fi

I don't think I should have to have two independent functions. There are only a few lines that differ. The actual functions have a lot more code, but it is completely duplicated between them.

I did not include my code for parsing the argument because I'm learning about getopt and haven't finished that part yet.

2
  • 1
    Why not also export force and move the if [[ $force == "y" ]] into the function?
    – meuh
    Oct 14, 2020 at 6:49
  • @meuh I like that idea. Post an answer and I'll accept it.
    – MountainX
    Oct 14, 2020 at 8:04

2 Answers 2

1

You can export force too and move the if [[ $force == "y" ]] into the function:

cmd() {
  if [[ $force == "y" ]] ; then
    git fetch; 
    git reset --hard HEAD; 
    git merge '@{u}:HEAD';
  else
    git pull;
  fi
  newpkg=$(makepkg --packagelist);
  makepkg -Ccr; 
  repoctl add -m $newpkg;
}

export -f cmd
export force
find . -mindepth 2 -maxdepth 2 -name PKGBUILD -execdir bash -c 'cmd' bash {} \;

4
  • Exported bash functions are a securty risk, unless this is limited to the scope of a script.
    – schily
    Oct 14, 2020 at 11:03
  • @schily - what is the best solution in this case?
    – MountainX
    Oct 16, 2020 at 17:43
  • Not using this feature in other cases.
    – schily
    Oct 16, 2020 at 18:46
  • @schily - it was nice of you to point out the potential security risk, but you have given so little info that it is of no help to me. Please elaborate.
    – MountainX
    Oct 17, 2020 at 4:16
1

You can use the function name as an argument:

if [[ $force == "y" ]] ; then
  USE=cmd_force
else
  echo "Call this with the -f option in case of: error: Your local changes to ... files would be overwritten by merge"
  USE=cmd_nice
fi

export -f $USE
find . -mindepth 2 -maxdepth 2 -name PKGBUILD -execdir bash -c $USE' {}' \;

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .