Я думаю, вы столкнулись с "Windows World" и " Unix World ".
То, что вы пытаетесь с rsync
, чтоЕстественный инструмент Unix, это копирование с использованием пути к пакетному файлу и помещение его в путь rsync.Это не будет работать.
Я расскажу ваш код:
В этой части вы все еще находитесь в "мире Windows", в котором вы используете FOR
для циклического прохождения по пути U:\0012\*
в способе windows FOR /d %%A IN (U:\0012\*) DO
.
Вы пытались "помочь" rsync
с путем стиля unix /cygdrive/U/0012/
, но переменная %%A
содержит путь стиля windows!
C:\cygwin\bin\rsync.exe -av -h --progress --checksum "/cygdrive/U/0012/%%A/*.*/" "/cygdrive/U/0012/%%A/EXAMPLE/"
Ошибка, которую вы получаете, вероятно, что-то вроде:
Источник и пункт назначения не могут быть оба удаленными.rsync error: синтаксис или ошибка использования (код 1) в main.c (1292) [Receiver = 3.1.2]
Как решить такую ошибку?
Сначала нужноскажем, я использую MSYS среду для инструментов Linux.Я проверил это на моих локальных файлах.
В пакетных файлах вы можете сделать это следующим образом:
@echo off
FOR /d %%A IN (U:\0012\*) DO (
SET "copy_path=%%A"
C:\msys64\usr\bin\cygpath.exe -u %copy_path% > tmp_file.tmp
SET /P unix_path=<tmp_file.tmp
DEL tmp_file.tmp
ECHO "%unix_path%"
C:\msys64\usr\bin\rsync.exe -av -h --progress --checksum --remove-source-files "%unix_path%" "%unix_path%/EXAMPLE/"
)
)
Сценарий принимает путь к окну C:\prg\PowerShell\test\SO\test1\*
а затем он использует cygpath.exe
для преобразования пути в путь в стиле Unix и сохраняет его во временный файл (tmp_file.tmp
).Затем он читает из временного файла путь в переменную unix %unix_path%
, которая затем используется в rsync.exe
.
Примечание: Как кто-то уже связал, как переместить файл с помощью rsync.Я просто укажу вариант.Вы должны добавить --remove-source-files
, который удаляет файлы после передачи.
** Edit **
- Думаю, теперь я понимаю, что вы имеете в виду.Теперь
rsync
действительно должен вести себя как движение.Разница лишь в том, что если каталог example
существует, он копируется в файл.(если это не так, то он создается и файлы перемещаются туда) - я думаю, что это были оригинальные намерения, когда я смотрел на mkdir && move
.
Что я сделал?
ENABLEDELAYEDEXPANSION
чтобы правильно прочитать переменные из файла (до того, как это было только последнее чтение)
"!unix_path!/"
последняя обратная косая черта действительно важна для правильного поведения rsync.
Я протестировал скрипт на своемкомпьютер и у меня все работает как надо.
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /D %%A IN (C:\prg\t\*) DO (
ECHO %%A
SET "copy_path=%%A"
C:\msys64\usr\bin\cygpath.exe -u !copy_path! > tmp_file.tmp
SET /P unix_path=<tmp_file.tmp
DEL tmp_file.tmp
ECHO "!unix_path!"
ECHO C:\msys64\usr\bin\rsync.exe -av --progress --checksum --remove-source-files "!unix_path!/" "!unix_path!/example/"
C:\msys64\usr\bin\rsync.exe -av --progress --checksum --remove-source-files "!unix_path!/" "!unix_path!/example/"
)
** Второе редактирование ** Пустые каталоги не удаляются с помощью rsync
Я не рекомендую использовать --remove-files
&& --delete
опции во время одной операции из-за того, что rsync может не работатьВы можете прочитать больше здесь superuser.com или обмен стека Unix или даже ошибка сервера .
Я бы просто пошел с уже написанным решением: Как удалить пустые папки с помощью командной строки Windows? (я говорю о решении (все кредиты автору), которое принимает также каталоги с пробелами):
for /f "usebackq delims=" %%d in (`"dir /ad/b/s | sort /R"`) do rd "%%d"
Последний скриптбудет выглядеть так:
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /D %%A IN (C:\prg\t\*) DO (
ECHO %%A
SET "copy_path=%%A"
C:\msys64\usr\bin\cygpath.exe -u !copy_path! > tmp_file.tmp
SET /P unix_path=<tmp_file.tmp
DEL tmp_file.tmp
ECHO "!unix_path!"
ECHO C:\msys64\usr\bin\rsync.exe -av --progress --checksum --remove-source-files "!unix_path!/" "!unix_path!/example/"
C:\msys64\usr\bin\rsync.exe -av --progress --checksum --remove-source-files "!unix_path!/" "!unix_path!/example/"
)
REM To delete empty directories - the windows way
REM save current directory to stack
pushd
cd C:\prg\t
REM Will delete all empty directories (subdirectories) at current path
for /f "usebackq delims=" %%d in (`"dir /ad/b/s | sort /R"`) do rd "%%d"
REM return to saved directory
popd