tags:

views:

51

answers:

3

Hi,

I want to put command option of rsync into a variable so I can reuse it for other rsync commands. Here is what I tried but it didn't work.

roption="-a --recursive --progress --exclude='class' --delete --exclude='exclude' --exclude='.svn' --exclude='.metadata' --exclude='*.class'"
rsync "$roption" /media/CORSAIR/workspace ~/

Can any body help me figure out the problem?

Thanks,

A: 

You can try the 'eval' command, which will ask the shell to parse the command line once before eval gets to interpret it:

roption="-a --recursive --progress --exclude='class' --delete --exclude='exclude' --exclude='.svn' --exclude='.metadata' --exclude='*.class'" 

eval "rsync $roption /media/CORSAIR/workspace ~"
Dasvid
eval is dangerous!
amphetamachine
can you elaborate for this case?
Dasvid
Try adding `| rm -Rf ~` to `$roption` and see where your `eval` gets you. :-P
Chris Jester-Young
+2  A: 

Use shell arrays. They're extremely useful if you want to form strings using escapes and have them be literally what is typed. Plus, security.

roption=(
    -a
    --recursive
    --progress
    --exclude='class'
    --delete
    --exclude='exclude'
    --exclude='.svn'
    --exclude='.metadata'
    --exclude='*.class'
)

rsync "${roption[@]}" /media/CORSAIR/workspace ~/

You can even add to them:

if [ "$VERBOSE" -ne 0 ]; then
    roption+=(--verbose)
fi
amphetamachine
Yay for an answer using arrays! +1
Chris Jester-Young
sorry for a beginner question, how can I make $VERBOSE to be true?
Son Nguyen
@Son Nguyen It was just an example variable, possibly implemented by using `getopts`. For this example, `VERBOSE=1` anywhere above the `if` call should do the trick.
amphetamachine
A: 

Since your $roption represents more than one argument, you should use $roption, not "$roption".

Of course, using a scalar to hold multiple values is just wrong. If you are using bash, consider using an array instead:

roptions=(-a --recursive --progress --exclude='class' --delete --exclude='exclude' --exclude='.svn' --exclude='.metadata' --exclude='*.class')
rsync "${roptions[@]}" /media/CORSAIR/workspace ~
Chris Jester-Young
"using a scalar to hold multiple values is just wrong" - Not wrong necessarily. Possibly insecure, yes. Lacking in scalability, yes. They fit in sometimes.
amphetamachine
Well, it's wrong in that its processing then depends on `$IFS`, which is, like you say, possibly insecure.
Chris Jester-Young