[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: cp output format



Le nonidi 29 messidor, an CCXXIII, Andrew McGlashan a écrit :
> Not sure if this is relevant enough, but I have a method to keep
> "source" files -- in this case .forward files in a controlled directory;
> if any of these differ from the target locations, then I save the target
> location file with a dated version and copy in the controlled source
> copy.  This way I only get new files if they are changed, you could use
> a similar method for the backups, that is only copying files to the
> backup area if they are different to the current copy in the source area.

If your files were all isolated in small hierarchies, I would have suggested
to use Git instead, but with dotfiles in several home directories, that is
not practical. And I realize you already considered that.

On the other hand, I suspect rsync (with option -c) can detect the files
that need updating in a simpler way.

Also:

> # cat fix_dot_forward.sh
> #!/bin/sh
> 
> PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
> 
> (
> wrk_dir=/backup/.forward-wrk
> 
> for fix_name in user1 user2 user3
> do

>         HOME_DIR=$(grep ^${fix_name}: /etc/passwd|cut -d: -f6)

"eval HOME_DIR=~$fix_name" is much simpler, more efficient, and would work
with NIS- or LDAP-based user databases.

> 
>         md5_1=$(md5sum $HOME_DIR/.forward|cut -d\  -f1)
>         md5_2=$(md5sum $wrk_dir/$fix_name/.forward|cut -d\  -f1)

You can write "md5="${md5%% *}" instead of using cut, one fork+exec less.

And you can write "md5sum < file" to have a dash instead of the file name,
and therefore not need to remove it.

This is minor in this case, but in newly written code, avoid MD5, better
use SHA-2.

And of course (unless the files are large (unlikely for .forward) and on the
same mechanical drive), cmp file1 file2 is much simpler.

>         if [ "$md5_1" != "$md5_2" ]
>         then
>                 echo "The .forward file has changed for: "$fix_name
>                 diff $HOME_DIR/.forward $wrk_dir/$fix_name/.forward|sed
> 's/^/   /'

>                 cp -p $HOME_DIR/.forward
> $HOME_DIR/${fix_name}.forward.$(date +%Y%m%d%H%M)

You do not check for errors.

>                 cp -p $wrk_dir/$fix_name/.forward $HOME_DIR/

Dangerous: if .forward is not very small (think: handmade mailing-list), cp
is not atomic. That means there is a small interval of time where the target
.forward file will be only partial.

To do that kind of thing reliably, you need to create a temporary file and
rename it once it is complete. Just use rsync for the copy, it does that by
default.

>         fi
> done
> )

Attachment: signature.asc
Description: Digital signature


Reply to: