В среде хостинга, в которой нет клиента rsync, я хотел бы выполнить действие, аналогичное тому, что делает rsync: отправлять только те файлы, которые были изменены.
Я бы выполнил эту однострочную запись в текущем каталоге. Это обновит archive.tar.gz измененными файлами, затем скопирует файл на удаленный сайт и, наконец, распакует его, оставив синхронизированные каталоги. У меня есть видение этого с использованием нескольких каналов, но я полагаю, что мне понадобится архив, чтобы действительно использовать инкрементную функцию.
Я теряюсь в синтаксисе tar при использовании инкрементального.
Это модифицированная версия DigitalRossсценарий:
#!/bin/bash
TarFile=fun.tgz
TheScript=$0
saveIFS="$IFS"
IFS=$'\n'
files=($( find -maxdepth 1 -type f -newer $TheScript -print ))
tmpfile=$(mktemp)
IFS="$saveIFS"
tar cvfz $TarFile "${files[@]}" && touch -r $tmpfile $TheScript
rm $tmpfile
это уменьшает шанс условий гонки за счет сохранения результата find
в массив и сразу же создав временный файл. Но это, конечно, не гарантия. Также этот скрипт избегает использования ls
. Еще одно преимущество состоит в том, что он обновляет метку времени сценария только в том случае, если tar
успешно. Он также будет обрабатывать имена файлов с пробелами.
Хм, если вы хотите переместить только измененные файлы, зачем команде tar обновлять архив? Если пересылаются только измененные файлы, разве tar-архив не будет состоять только из них и не обязательно будет создаваться каждый раз с нуля?
Если я правильно понимаю, вы хотите что-то вроде этого, я называю это bozosync.sh
:
TarFile=fun.tgz
TheScript=$0
result=
ls -1 . | (
while read f; do
if [ -f "$f" -a $f -nt $TheScript ]; then
result="$result $f"
fi
done
tar cvfz $TarFile $result
touch $TheScript
)
Это помещает каждый простой файл в текущий каталог в tar-архив для каждого файла, который новее, чем сам скрипт, а затем запускается touch(1)
в скрипте, чтобы обновить время его модификации. У этого действительно есть состояние гонки, в котором файл, который был изменен между тестом и касанием, будет проигнорирован в следующий раз. Если это проблема, вы можете обойти ее, скопировав сценарий до цикла, а затем переместив его обратно в себя в конце. (Тогда у вас все еще есть гонка, но ошибка более мягкая, она может просто включать файл, который на самом деле не изменился.)
Я внес несколько изменений после тестирования, но это отлично работает, спасибо.
#!/bin/bash
TarFile=transfer-me.tar.gz
TheScript=$0
saveIFS="$IFS"
IFS=$'\n'
files=($(find . -maxdepth 1 -newer $TheScript -print))
unset files[0]; #remove "."
tmpfile=$(mktemp temp.XXXXXX)
IFS="$saveIFS"
elements=${#files[@]}
if [ "$elements" -gt "0" ]; then
tar cvfz $TarFile --exclude ".svn" --exclude ".swp" --exclude "Icon?" --exclude ".DS_Store" --exclude "$TarFile" "${files[@]}" && touch -r $tmpfile $TheScript
fi
rm $tmpfile;