0

I am trying to write bash-script with user input. Script gets user input and build find command with data from input(Use parameter if they aren't empty). I was reading about bash expansion from here and i did something like :

 eval find $USERPATH "${USERNAME:+'-name' \"\$USERNAME\"}" "${USERSIZE:+'-size' \"\$USERSIZE\"}" "${USERDATA:+'-mmin' \"\$USERDATA\"}"

It's work great, but i want to search by content, so i need add

-exec fgrep -l $USERCONTENT {} \;;

but i can't. I was trying something like this

 "${USERCONTENT:+'-exec fgrep -l' \"\$USERCONTENT {}\;;'\"}"

but it doesn't work. I don't know how i can do this in good way.

Farfax
  • 3
  • 1
  • 1
    Why do you need eval at all? Try removing all quotes and simply place double quotes around the variable where it is inside the {}, ${USERSIZE:+-size "$USERSIZE"} – grail Mar 31 '17 at 15:51
  • As an aside, all-caps names are specified by POSIX convention for names with meaning or the operating system or shell, whereas lowercase variable names are reserved for application use. See http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html – Charles Duffy Mar 31 '17 at 16:03
  • BTW, see [BashFAQ #50](http://mywiki.wooledge.org/BashFAQ/050) ("I'm trying to put a command in a variable, but the complex cases always fail!") – Charles Duffy Mar 31 '17 at 16:04

1 Answers1

4

It is far simpler to collect the arguments in an array.

find_args=( "$USERPATH" )
[[ -n "$USERNAME" ]] && find_args+=(-name "$USERNAME")
[[ -n "$USERSIZE" ]] && find_args+=(-size "$USERSIZE")
[[ -n "$USERDATA" ]] && find_args+=(-mmin "$USERDATA")
[[ -n "$USERCONTENT" ]] && find_args+=(-exec fgrep -l "$USERCONTENT" {} \;)
find "${find_args[@]}"
chepner
  • 497,756
  • 71
  • 530
  • 681
  • 1
    ...simpler, *and* much less bug-prone. This way we don't need to worry about `USERCONTENT='$(rm -rf $HOME)'` being executed. – Charles Duffy Mar 31 '17 at 16:03