Непонятно, зачем вам нужно создавать все эти каталоги, используя 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'