rsync parameters errors

Joe josephj at main.nc.us
Thu Jan 24 20:24:29 MST 2013


THANK YOU! That method of handling parameters is new to me.  I have read
several bash programming books and it wasn't in there.
It does work *way* better than what I was doing.

More replies inline.

If anyone feels this is too off topic for this list, I'd be happy to
continue it a bit off list if anyone wants to go there with me.

Is there a bash tutorial that *explicitly covers this technique* and all
its dos and don'ts?

Joe
On 01/24/2013 05:58 PM, Volker Kuhlmann wrote:
> On Fri 25 Jan 2013 00:08:52 NZDT +1300, Joe wrote:
>
>> In my new bash script, I'm doing what I think is a very simple rsync
>> command the way I'm used to doing it.  I just do a lot of setup and
>> checking before I get to it.
>>
>> When I run it, it gets very unhappy with me.  It's probably something
>> very simple.
> Your problem is with shell programming, not rsync, but that is
> frequently a requirement with rsync because of its stellar argument
> lists...
I know!  Thanks for going slightly off topic to help me.
>
>> ##COMMAND="rsync ${DRY_RUN} -avushi ${DELETE} --stats --progress
>> --log-file=\"${LOGFILE1}\" \"${MOUNT_POINT[0]}/${DIRECTORY[0]}/\"
> ARRGGHHH. 
>
> Do yourself a favour and increase the legibility and coding standard of
> your programs no end by using array variables that hold argument lists
> only but no commands, and preferably no arguments that need a path name.
Because embedded commands and path names take you back into quoting hell
with embedded blanks and because bash arrays and strings are one
dimensional and can't readily handle nested constructs.
> Like this
>
>   rsyncargs=(
>       -avushi
>       -stats
>       #--log-file=  # don't do this, you will be paying for it
>   )
>
>   LOGFILE="..."
>
>   logargs=(
>       ....
>   )
>   
It looks like the reason for not nesting arguments is that it will get
you back into the quoting hell this method is designed  to avoid.
> Make it a rule to always program in a way that allows spaces in every
> argument. Anything going belly-up with a space in a file name is plain
> incompetent.
I always do when I'm planning to use a script more than a few times.  I
had escaped quotes in my original version, but took them out to simplify
things until I got it to work at all.  (Stepwise regression instead of
stepwise refinement ;)    )  With your method, it looks like doing so
will be at least an order of magnitude easier!
> Then run your commands
>
>   rsync "${rsyncargs[@]}" --log-file="$LOGFILE" | tee "${logargs[@]}"
>
> You could set LOGFILE to /dev/null if desirable.
>
> Avoid having to eval huge strings, it's always risky and almost always
> bad, and avoid putting variables that need to be expanded later into
> argument lists held by other variables. That way you solve all your
> problems with when "|" is expanded, having to quote variables containing
> paths twice and so on, and your code stays legible and maintainable.
That makes perfect sense.  With your coding method, that will also be
much easier to do. too.

The main place that's still a problem is in passing arguments to
functions and scripts. It looks like the same technique will work for
that too.

Expansions are a major strength of bash, but I've spent many hours
trying to get them right.  They stop when they feel like it, not when
you want them to.
>
> If you need progress logging, I've found this to be easy, safe and
> effective (at the cost of a bit of performance - which you're not caring
> about as you're using bash):
>
>   Log() {
>       if [ -n "$logging" ]; then
>           (
> 	  set -x
> 	  "$@"
> 	  )
>       else
>           "$@"
>       fi
>   }
>
>   Log yourcommand
Nice.  It took me a moment to see the subshell there.

That works, but is a bit tricky because it intentionally resets the
environment at the end and thus limits communication with any subsequent
code.

Since bash can't return parameters, it's all about side effects.

Right now, I'm using a sourced file ~/bin/bash_trace that contains
shopt -s -o xtrace  # debug
shopt -s -o verbose  # debug

That way, I can comment out/uncomment one line and it turns both back
off/on.

>
> Don't bother trying to be compatible with other *sh-type shells on other
> *nix systems, trying to get any use out of such retarded constructs only
> leads to mental illness.
LOL!  In my public project (duplexpr on sourceforge), I started out
writing everything with #!/bin/sh.

One day somebody changed something in bash/sh and all of my working
scripts died with syntax errors that made no sense to me.
To fix it, all I had to do was change to #!/bin/bash.

After that happened, I gave up on sh.  It seems like what you get when
you invoke it isn't all that standard anyway and almost everyone has bash.
>
> HTH,
>
> Volker
>



More information about the rsync mailing list