Вот один для мастеров удара-fu. Нет, на самом деле я просто шучу, Вы будете все, вероятно, знать это за исключением меня..
Я пытаюсь создать резервный сценарий оболочки. Идея довольно проста: найдите файлы в определенной папке, более старой, чем 7 дней, tar/gzip их к другому каталогу, и удалите их. Проблема, я не уверен, будет ли у меня достаточно полномочий создать tar/gzip файл в целевом dir. Есть ли любой (надлежащий) способ проверить, был ли файл создан успешно, и если так, удаляет файлы. Иначе пропустите ту часть и не уничтожайте данные клиентов. Я слышу, что они не очень любят это.
Вот то, что я имею до сих пор:
01: #!/bin/bash
02:
03: ROOTDIR="/data/www"
04:
05: TAR="${ROOTDIR}/log/svg_out_xml/export_out_ack_$(date +%Y-%m-%d).tar"
06: cd ${ROOTDIR}/exchange/export/out_ack/
07: find . -mtime +7 -type f -print0 | xargs -0 tar -cf "${TAR}"
08: gzip ${TAR}
09: find . -mtime +7 -type f -print0 | xargs -0 rm -f
В основном я должен был бы проверить, пошло ли все прекрасное на строках 7 и 8, и раз так выполнитесь 9.
Кроме того, я хотел бы сделать файл журнала из этих операций, таким образом, я знаю, что все пошло прекрасное (это - ночное задание крона).
Для ведения журнала вы можете заключить разделы вашего скрипта в фигурные скобки и перенаправить стандартный вывод в файл журнала:
{
script_command_1
script_command_2
script_command_3
} >> /path/to/log_file
Для ведения журнала вы можете организовать, чтобы весь вывод, записанный на стандартный вывод и / или стандартная ошибка, направлялся в файл. Таким образом, вам не нужно перенаправлять вывод каждой команды:
# Save standard output and standard error
exec 3>&1 4>&2
# Redirect standard output to a log file
exec 1>/tmp/stdout.log
# Redirect standard error to a log file
exec 2>/tmp/stderr.log
# Now the output of all commands goes to the log files
echo "This goes to /tmp/stdout.log"
echo "This goes to /tmp/stderr.log" 1>&2
...
# Print a message to the original standard output (e.g. terminal)
echo "This goes to the original stdout" 1>&3
# Restore original stdout/stderr
exec 1>&3 2>&4
# Close the unused descriptors
exec 3>&- 4>&-
# Now the output of all commands goes to the original standard output & error
...
Чтобы выполнить команду, только если предыдущая завершилась успешно, вы можете связать их с условными операторами:
# Execute command2 only if command1 succeeds, and command3 only if both succeed:
command1 && command2 && command3
# Execute command2 only if command1 fails
command1 || command2
, чтобы вы могли выполнять такие действия, как
{ find . -mtime +7 -type f -print0 | xargs -0 tar -cf "${TAR}" &&
gzip ${TAR} &&
find . -mtime +7 -type f -print0 | xargs -0 rm -f } ||
{ echo "Something failed" 1>&2; exit 1 }
или укажите подробности в выводе журнала:
find . -mtime +7 -type f -print0 | xargs -0 tar -cf "${TAR}" ||
{ echo "find failed!!" 1>&2; exit 1 }
gzip ${TAR} ||
{ echo "gzip failed!!" 1>&2; exit 1 }
find . -mtime +7 -type f -print0 | xargs -0 rm -f ||
{ echo "cleanup failed!!" 1>&2; exit 1}
GNU tar имеет --remove-files
, который будет удалять файлы после их добавления в архив. v
заставит его выводить список файлов по мере их добавления. z
будет передавать tar через gzip на лету.
Ваше решение find
является небрежным; файл может соответствовать критериям в промежутке между вызовами, поэтому он будет удален, но не записан в резервную копию.
Простой выход, но без явного сообщения об ошибке, добавьте -e
в шебанг, то есть #! / Bin / sh -e
, что приведет к завершению работы оболочки в случае сбоя команды.
Я полагаю, что Cron должен выдать вам сообщение об ошибке по почте.
Если вы хотите использовать полноценную схему резервного копирования, я бы посоветовал вам использовать то, что уже было сделано. Их много, и большинство из них работают очень хорошо.