Бэкап из теневой копии

Итак, я хочу сделать резервную копию из теневой копии с помощью пакетного скрипта. Это то, что у меня есть до сих пор:

vssadmin list shadows | findstr /C:"Volume da Cópia de Sombra"

Выход:

     Volume da Cópia de Sombra: \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1
     Volume da Cópia de Sombra: \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy2
     Volume da Cópia de Sombra: \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy5

Мне нужно получить только путь в последней строке, возвращаемый findstr, но я действительно не знаю, как это сделать.

И после получения пути и добавления \ в конец (символическая ссылка будет создана только в том случае, если путь заканчивается на \), сделайте на него символическую ссылку.

mklink c:\shadowcopy /d %path%

Итак, я потерялся в середине этого.

Я нашел этот вопрос с ответом:

Пакетный файл для вывода последней строки findstr

Но чувак, пакетный синтаксис - это беспорядок, и я не понимаю ни строчки кода в ответе, чтобы адаптировать его к моему проекту.

Может ли кто-нибудь помочь мне и подробно объяснить, что мне нужно сделать (или код, если вы его предоставите), чтобы я мог понять, что я делаю, а не просто вставлять и копировать и, кто знает, внести некоторые улучшения/изменения.


person Rafael    schedule 19.11.2015    source источник


Ответы (1)


Всякий раз, когда вы хотите захватить вывод команды, используйте for /f. Я полагаю, что в этом случае удобным разделителем будет ?.

Этот фрагмент создаст ссылки для всех теневых копий.

if not exist c:\shadowcopy md c:\shadowcopy
for /f "tokens=2 delims=?" %%I in ('vssadmin list shadows ^| find "GLOBALROOT"') do (
    mklink /d c:\shadowcopy\%%~nxI \\?%%I\
)

Этот фрагмент создаст одну ссылку из последней совпадающей строки теневого списка.

for /f "tokens=2 delims=?" %%I in ('vssadmin list shadows ^| find "GLOBALROOT"') do (
    set "target=\\?%%I\"
)
mklink /d c:\shadowcopy %target%

Увидеть разницу? В первом блоке кода mklink срабатывает на каждой итерации цикла for /f и создает множество символических ссылок; тогда как во втором блоке set перезаписывает значение, хранящееся в %target%, при каждой итерации. mklink выполняется вне цикла и поэтому создает только одну символическую ссылку. Я думаю, это секретный соус, который вы ищете.

В консоли cmd введите help for для получения дополнительной информации о циклах for /f.

person rojo    schedule 19.11.2015
comment
Почему ^ перед трубой? - person Rafael; 19.11.2015
comment
Потому что труба не заключена в двойные кавычки и будет преждевременно рассматриваться как буквальный разделитель команд. Попробуйте без него и посмотрите, что получится. Без этого интерпретатор cmd обрабатывает канал как конец команды for, а не как конец команды vssadmin, как мы хотим. Выход из канала с помощью знака вставки задерживает оценку канала до тех пор, пока не будет запущена команда vssadmin. - person rojo; 19.11.2015
comment
Хм, я понял. Итак, ^ - это экранирующий символ в пакете? Имеет смысл, так как \` широко используется в пакетном режиме. Спасибо большое. РЕДАКТИРОВАТЬ: Пришлось отредактировать, потому что `\` здесь является экранирующим символом, поэтому необходимо добавить двойной xD - person Rafael; 19.11.2015
comment
@Rafael, команда FINDSTR использует \ для экранирования в регулярных выражениях. И если вам нужно экранировать символ процента, вы удваиваете символы процента. Просто пара особенностей партии. - person Squashman; 19.11.2015
comment
Это просто идеально - person Medhat Fawzy; 10.12.2020