Решение, в чем-то похожее на решение Марка , но не требующее изменений в /etc/fstab
или монтирования и размонтирования файловых систем:
#!/bin/sh
lockdir=/tmp/file-copy.lock
if ! mkdir "$lockdir"; then
echo 'File copy already in progress' >&2
exit 1
fi
trap 'rmdir "$lockdir"' EXIT
PATH=$PATH:/usr/local/bin
rsync -ai...
Несколько замечаний по этому поводу:
mkdir
— атомарная операция, очень похожая на mount
, которая завершится ошибкой, если каталог уже существует, но создаст каталог, если его нет. Это безопаснее, чем сначала проверять блокировку файла , а затем создавать его (в два этапа с возможностью состояния гонки в -между ).
Ловушка EXIT
гарантирует, что каталог блокировки будет удален при завершении сценария. Каталог блокировки также будет удален при перезагрузке (системой ), поскольку он находится в /tmp
.
Я установил PATH
в соответствующее значение, а не вызывал rsync
с его полным путем. Это чисто косметическая вещь, но она может быть полезна, если позже скрипт будет расширен для использования других команд из набора портов OpenBSD (, таких как restic
илиborgbackup
).
Опция -z
для rsync
необходима только при очень медленных сетевых подключениях (, когда сжатие/распаковка данных выполняется быстрее, чем пропускная способность сети ), и никогда для локального копирования. Я также предпочитаю-i
(--itemize-changes
)вместо -v
(--verbose
), так как это точно скажет мне, почему файл был передан.
Для безопасного резервного копирования больших объемов данных я обычно рекомендую использовать специально написанное программное обеспечение для резервного копирования поверх rsync
, напримерrestic
илиborgbackup
. Эти два дополнительно выполняют дедупликацию и шифрование данных, а borgbackup
может дополнительно выполнять сжатие. restic
хорош в том смысле, что позволяет сохранять резервные копии на внешний сервер (поверх, например. sftp
), даже если на этом сервере не установлено restic
, тогда как borgbackup
требует, чтобы программное обеспечение было установлено в целевой системе. И restic
, и borgbackup
управляют блокировкой хранилища резервных копий.
Печать типа файла вместе с именем с помощью-printf "%y %p\n"
:
$ sudo find. -name 'example.com*' -printf "%y %p\n"
d./archive/example.com
f./renewal/example.com.conf
d./live/example.com
Использование -printf
предполагает, что GNUfind
(является наиболее распространенной find
реализацией в системах Linux ).
Я бы назвал ls
на нем:
# find. -name example.com\* -print0 | xargs -0 ls -ld
Если вам нужно выполнить find
и ls
как root
, а вы этого не делаете, вы можете сделать:
# sudo bash -c "find. -name example.com\* -print0 | xargs -0 ls -ld"
Количество обратных косых черт перед звездочкой *
может зависеть от вашей оболочки -возможно, вам нужно 0 или 1 из них внутри кавычек ""
.
Вы можете использовать file
так:
sudo find. -name "example.com*" -print0 | xargs -0 sudo file
Пример вывода:
$ sudo find. -name "example.com*" -print0 | xargs -0 sudo file
./example.com. big file: ASCII text
./example.com-dir: directory
./example.com: empty
Найди дважды:
echo 'directories'
find. -name 'example.com*' -type d
echo 'non-directories'
find. -name 'example.com*' ! -type d
Обратите также внимание на цитирование шаблона, используемого для проверки имени. Без кавычек оболочка попытается сопоставить строку с именами в текущем каталоге перед вызовом find
. Если параметр оболочки failglob
был установлен в оболочке bash
или если параметр оболочки NOMATCH
в zsh
не был отключен, шаблон подстановки без кавычек, который ничему не соответствует, вызовет ошибку оболочки, и find
вообще не будет вызываться.
В качестве альтернативы можно просто вывести косую черту в конце пути к каталогу (так ls -p
будет представлять каталоги):
find. -name 'example.com*' \( -type d -exec printf '%s/\n' {} \; -o -print \)
Приведенная выше команда find
сначала проверяет правильность имени. Если это так и это каталог, он вызывает printf
для вывода пути к каталогу с косой чертой в конце. Если это не каталог, -print
используется для вывода пути как есть.
В GNU find
бит -exec printf '%s/\n' {} \;
можно заменить на -printf '%p/\n'
.
Со стандартным find
вы также можете использовать -exec printf '%s/\n' {} +
для вызова внешней утилиты printf
как можно меньше раз, но это будет означать, что каталоги, скорее всего, будут выводиться последними или, по крайней мере, в пакетном режиме.
Другая альтернатива состоит в том, чтобы фактически использовать ls -p
, чтобы отличить каталоги от других типов файлов. При использовании ls -p
каталог будет указан с завершающим символом /
, как и выше.
find. -name 'example.com*' -exec ls -f -d -p {} +
Здесь я использую -f
, чтобы не позволить ls
сортировать вывод, и -d
, чтобы избежать вывода содержимого каталогов.
Вы можете использовать ls -F
вместо ls -p
, чтобы поставить другие метки для типов файлов, отличных от каталогов. Например, исполняемые файлы будут иметь суффикс *
, а символические ссылки будут иметь суффикс @
.
И -p
, и -F
(, и -f
, и-d
)являются стандартными опциями утилиты ls
.
Если вам нужен более портативный вариант, который будет работать с *вариантами nix без опции gnu -printf
(macOS, например ), вы можете добавить косую черту в конец пути к каталогу через ls
вот так:
find. -name "example.com*" -exec ls -dF {} \;
пример:
$ sudo find. -name "example.com*" -exec ls -dF {} \;
./archive/example.com/
./renewal/example.com.conf
./live/example.com/
Это также оказалось в формате, более подходящем для дальнейшей передачи в большее количество команд unix.