Ответ 1
Переключатель /I
(не /F
как вы упомянули в своем вопросе) не позволяет xcopy
узнать, является ли пункт назначения файлом или каталогом только в том случае, если задано несколько исходных файлов, поэтому, если источник является каталогом или являются подстановочными знаками ?
или *
. Если назначение уже существует, такое приглашение никогда не появляется.
Существуют следующие сценарии (в зависимости от предоставленных значений %source%
и %target%
):
-
один исходный файл, целью является файл:
переключатель
/I
бесполезен, поэтому вам нужно передатьF
в командную строкуxcopy
:echo F|xcopy /S /Q /Y /F "%source%" "%target%"
при условии, что задан переключатель
/Y
(для принудительной перезаписи), вы также можете заранее создать целевой файл (пустой файл):>> "%target%" rem/ xcopy /S /Q /Y /F "%source%" "%target%"
-
один исходный файл, назначение - это каталог:
переключатель
/I
тоже бесполезен; вы можете подключитьD
к командной строкеxcopy
:echo D|xcopy /S /Q /Y /F "%source%" "%target%"
или вы можете просто добавить
\
к месту назначения:xcopy /S /Q /Y /F "%source%" "%target%\"
хотя это вызывает проблемы, когда
%target%
указывает текущий каталог диска, такого какD:
например, посколькуD:
означает текущий каталог этого диска, тогда какD:\
означает его корневой каталог;или вы создаете каталог назначения заранее:
2> nul mkdir "%target%" xcopy /S /Q /Y /F "%source%" "%target%"
2> nul
часть подавляет сообщение об ошибке в случае, если каталог уже существует; -
несколько исходных файлов, целью является файл:
это обычно бессмысленная ситуация, потому что вы скажите
xcopy
скопировать каждый исходный файл в один и тот же файл назначения, пытаясь его перезаписать; -
несколько исходных файлов, назначение - это каталог:
переключатель
/I
имеет смысл здесь:xcopy /S /I /Q /Y /F "%source%" "%target%"
опция трубы также работает здесь:
echo D|xcopy /S /Q /Y /F "%source%" "%target%"
поэтому добавление
\
в пункт назначения (в отношении ограничения, указанного выше):xcopy /S /Q /Y /F "%source%" "%target%\"
или вы создаете каталог назначения заранее:
2> nul mkdir "%target%" xcopy /S /Q /Y /F "%source%" "%target%"
Вывод
Наиболее гибким и безопасным решением является передача нужного выбора (F
или D
) в командную строку xcopy
. (Обратите внимание, что запрос зависит от языка.)
дополнение
В фрагменте кода есть некоторые незначительные проблемы, которые я хочу упомянуть здесь:
- вы обычно должны использовать
\
как разделитель путей, поскольку для этой цели это стандартный символ Windows (хотя/
в большинстве случаев работает); - есть
-1111
добавленный к вашей второйnet use
командной строке; если это составляет пароль для ресурса, его следует перенести до опции/USER
; иначе просто удалите его; - ваши
set
командные строкиset
проблемы с некоторыми специальными символами (например,&
,^
,(
,)
); чтобы избежать этого,set "source=%~1"
иset "target=p:/%~2"
;~
удаляет потенциал окружающий""
из аргументов (которые необходимы, если они содержат SPACE,,
,;
,=
);
Вот код со всеми перечисленными выше вещами:
net use P: /DELETE
rem supposing '-1111' constitutes the password for the resource:
net use P: "\\200clan\F_Drive" -1111 /USER:adm /PERSISTENT:NO
set "source=%~1"
set "target=P:\%~2"
echo "%source%" "%target%"
rem supposing the destination is a directory:
echo D|xcopy /S /I /Q /Y /F "%source%" "%target%"
rem actually you do not need any interim variables:
REM echo D|xcopy /S /I /Q /Y /F "%~1" "P:\%~2"