LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   find in bash script returns "missing argument to `-exec'" while cmd runs fine (http://www.linuxquestions.org/questions/programming-9/find-in-bash-script-returns-missing-argument-to-%60-exec-while-cmd-runs-fine-925943/)

zhjim 01-27-2012 05:17 AM

find in bash script returns "missing argument to `-exec'" while cmd runs fine
 
Hi folks,

i wrote a little shell script involving find. I use variables to construct the final find command. While running the echoed find command on cmd line everything works fine but inside the bash script find returns "/usr/bin/find: missing argument to `-exec'". Anyone can help me out on this?

Code:

#!/bin/bash
#############
# zip'em up #
#############

# Files older than btime are tared
btime="+0"                              # has to be zero to take last day into account
# Which directory to start from
startd="/usr/coremedia/cap-solr-replication/jakarta-tomcat/logs"
saved="./moved"

TAR_CMD="/bin/tar"
TAR_OPT="--remove-files -czf"
TAR_SUF="tar.gz"

FIND_CMD="/usr/bin/find"
FIND_OPT="-daystart -maxdepth 1 -mtime $btime"
#FIND_EXC_TAR="-execdir $TAR_CMD $TAR_OPT '{}'.$TAR_SUF {} \;"
#FIND_EXC_MV="-execdir $MV_CMD {} $saved"
FIND_EXC_TAR="-exec ls \{\} \;"
FIND_EXC_MV="-exec ls \{\} \;"

# Tar files older than btime
echo "Finding files older than today and tar'em"
TAR_EM="$FIND_CMD $startd $FIND_OPT $FIND_EXC_TAR"
echo -e $TAR_EM
$TAR_EM

# move tar files into moved
echo 'Moving files that end of ' $TAR_SUF
MV_EM="$FIND_CMD $startd -name '*.'$TAR_SUF $FIND_EXC_MV"
echo -e $MV_EM
$MV_EM


kbp 01-27-2012 06:23 AM

I haven't tested but you may be finding files with spaces in the path, try adding some quotes.

NevemTeve 01-27-2012 07:01 AM

Code:

FIND_EXC_TAR="-exec ls \{\} \;"
FIND_EXC_MV="-exec ls \{\} \;"

instead:
Code:

FIND_EXC_TAR="-exec ls {} ;"
FIND_EXC_MV="-exec ls {} ;"


grail 01-27-2012 07:02 AM

More often than not you will find it better to place commands into a function and call it then using variables which may perform unexpectedly.

zhjim 01-27-2012 07:33 AM

@kdp: So where should I add the quotes?

@NevemTeve: That way it works, thanks a lot. I guess its the way bash handles variables. You have an idea where I can read up on this in more depth? As man find says that one has to escape {} and ;...

@grail: I'll consider this.

catkin 01-27-2012 08:25 AM

Quote:

Originally Posted by zhjim (Post 4585794)
@NevemTeve: That way it works, thanks a lot. I guess its the way bash handles variables. You have an idea where I can read up on this in more depth? As man find says that one has to escape {} and ;...

From Grouping Commands (about {}): "Bash provides two ways to group a list of commands to be executed as a unit. When commands are grouped, redirections may be applied to the entire command list. For example, the output of all the commands in the list may be redirected to a single stream" and "Placing a list of commands between curly braces causes the list to be executed in the current shell context". A bare {}, is thus an empty list of commands and the shell will discard it. This meaning may be removed by backslash escaping the { and the } as the find command man page suggests or by putting it in quotes as '{}' to ensure it is passed to find. Your problem was that you were doing both -- quoting and escaping. The result was that \{\} was passed to find instead of {}.

From Looping Constructs (about ;): "Note that wherever a ‘;’ appears in the description of a command's syntax, it may be replaced with one or more newlines ". As for {}, this meaning may be removed by escaping or quoting but using both passes \; to find.

David the H. 01-29-2012 07:54 AM

Read here for why you shouldn't store command syntax in a variable:

http://mywiki.wooledge.org/BashFAQ/050

Do as grail suggested and set it up as a function. Or if you absolutely insist on using variables, at least put it an array and store each option in a separate position.

zhjim 01-30-2012 07:23 AM

Thanks to be both of you catkin and David. I already skimed over the links but are about to understand them fully.

So catkin if I understand it right you say that.
Code:

" \{\} "
is both qouting and escaping. I always thought that "" (double quotes) is a quotation that allows interpretation of special characters in contrast to '' (single quotes). But I'm not sure if this also implies escaping.

I'll just have myself another look at the bash man page as well as the BASH Scripting Tutorial to get on better ground. I think I have to dig some more on how bash interprets files in relation to command lines.

catkin 01-30-2012 08:14 AM

From the GNU Bash Reference on Double Quotes: "The backslash retains its special meaning only when followed by one of the following characters: $, `, ", \, or newline. Within double quotes, backslashes that are followed by one of these characters are removed. Backslashes preceding characters without a special meaning are left unmodified".

zhjim 01-31-2012 05:52 AM

All right. Thanks catkin.

catkin 01-31-2012 06:47 AM

If the problem is now solved you can mark the thread SOLVED via the Thread Tools menu.

EDIT: actually you can mark it SOLVED whether or not it is actually solved ... but you know what I am expressing badly.

zhjim 01-31-2012 09:56 AM

thanks for the reminder. Jup the problem itself is solved.


All times are GMT -5. The time now is 06:07 PM.