Home > OS >  Unable to run the find command from within a function
Unable to run the find command from within a function

Time:10-19

I'm trying to setup a flexible way of running the find command by using a function.

I've tried the following code:

#!/bin/bash
#
if [ $UID -ne 0 ]; then echo Please run this script as root; exit 1; fi
#
# create unique tmp file to store o/p
temp=$(basename $0)
TMPFILE=$(mktemp -q /tmp/${temp}.XXXXXX)
if [ $? -ne 0 ]; then
  echo "$0: Can't create temp file, exiting..."
  exit 1
fi
#
# create a function to store the find command
findCom () {
# $1 is the userid
local userid=$1
# $2 is the groupid
local groupid=$2
echo "in findCom"
echo "userid is $userid"
echo "groupid is $groupid"
echo "tmpfile is $TMPFILE"
commonComs='find / -not \( -path /proc -prune \) -not \( -path /sys -prune \) -not \( -path /usr/src -pru
ne \) -not \( -path /home -prune \) -not \( -path /dev -prune \) -not \( -path /tools -prune \) -not \( -
path /mnt -prune \) -not \( -path /blfs-commands -prune \) -not \( -path /blfs-html -prune \) -not \( -pa
th /blfs-sources -prune \) -not \( -path /blfsBuildFiles -prune \)'
userbit=' -user $userid '
groupbit='-group $groupid '
endbit='| sort -u > $TMPFILE'
finalCom="${commonComs}${userbit}${groupbit}${endbit}"
echo "$finalCom"
bash "$finalCom"
}
#
echo "tmpfile is $TMPFILE"
userid=gzip
groupid=gzip
findCom $userid $groupid

#find / -not \( -path /proc -prune \) -not \( -path /sys -prune \) -not \( -path /usr/src -prune \) -not 
\( -path /home -prune \) -not \( -path /dev -prune \) -not \( -path /tools -prune \) -not \( -path /mnt -
prune \) -not \( -path /blfs-commands -prune \) -not \( -path /blfs-html -prune \) -not \( -path /blfs-so
urces -prune \) -not \( -path /blfsBuildFiles -prune \) \( -user $userid -a -group $groupid \) | sort -u 
> $TMPFILE

It works fine if I run the find command (commented out) at the end of the main program. If I run it from within the function I get:

bash: find / -not \( -path /proc -prune \) -not \( -path /sys -prune \) -not \( -path /usr/src -prune \) -not \( -path /home -prune \) -not \( -path /dev -prune \) -not \( -path /tools -prune \) -not \( -path /mnt -prune \) -not \( -path /blfs-commands -prune \) -not \( -path /blfs-html -prune \) -not \( -path /blfs-sources -prune \) -not \( -path /blfsBuildFiles -prune \) -user $userid -group $groupid | sort -u > $TMPFILE: No such file or directory'

I assume it's a problem with the quotes, but I've tried different quotes and can't find a way to get it to work.

Any help would be much appreciated.

CodePudding user response:

I think you need to use this to execute the final command:

bash -c "$finalCom"

Without -c you ask bash to execute the file/path $finalCom.

CodePudding user response:

I'd suggest using an array to store the find command you want to execute:

findcommand=("find" "/" "-not" ...)
findcommand =("-user" "$userid")
findcommand =("-group" "$groupid")
echo "${findcommand[@]}"
"${findcommand[@]}" | sort -u > "$TMPFILE"

This should be safer, more flexible and will also handle stuff like spaces and escaping better.


That being said, you should also mind that there's a difference between '<str>' and "<str>". I think you want to use double quotes here:

userbit=" -user $userid"
groupbit=" -group $groupid"
endbit=" | sort -u > $TMPFILE"

With single quotes, you get a string as is. With double quotes, variables (here $userid, $groupid, $TMPFILE) are expanded with their values.

  • Related