Непонятно, зачем вам нужно создавать все эти каталоги, используя mkdir
.
Единственный каталог, который вам нужно создать, это сам каталог назначения, и это только в том случае, если он еще не существует. rsync
создаст все подкаталоги, если вы используете опцию -a
или -v
.
Примерно так должно быть достаточно:
destdir="/home/local_directories/onedir.bak" # or wherever it should go
ssh user@server "mkdir \"$destdir\""
rsync -a /home/local_directories/onedir/ user@server:"$destdir"
Или правильнее (только создание каталога, если он не существует):
destdir="/home/local_directories/onedir.bak"
ssh user@server 'destdir="'"$destdir"'"; test -d "$destdir" || mkdir -p "$destdir"'
rsync -a /home/local_directories/onedir/ user@server:"$destdir"
Но если вам действительно нужно это сделать, и по какой-то причине действительно требуется ls -ltds
, вам придется исправить свой бит {xargs}
чтобы он заработал .
Самый правильный и эффективный способ сделать последний шаг -
find ... |
ssh user@server 'while IFS=$'"\n"' read -r dir; do test -d "$dir" || mkdir -p "$dir"; done'
Идея заключается в том, что мы только начинаем find
и ssh
один раз. Мы начинаем find
и ssh
вместе в конвейере, и команда find
отправляет свой вывод на удаленный сервер через ssh
.
find
производит одну строку вывода на файл, затем цикл while read
while с другой стороны читает по одной строке за раз и что-то делает с ней (в этом случае создает каталог).
Если вы используете xargs
, он будет запускать ssh
несколько раз, что замедлит работу.
Лучше, но немного сложнее, это:
find ... -print0 |
ssh user@server 'while read -r -d "$(printf "\000")" -r dir; do test -d "$dir" || mkdir -p "$dir"; done'
Это лучше, потому что он обрабатывает странные символы в файлах, включая символы новой строки, которые очень редки, и плохая идея, но лучше обрабатывать их на всякий случай.
Так что, насколько я понимаю, вы должны просто делать что-то вроде:
find /home/local_directories/onedir/ -type d -print0 |
ssh user@server 'while read -r -d "$(printf "\000")" -r dir; do test -d "$dir" || mkdir -p "$dir"; done'