【问题标题】:Multiple argument looping in batch files批处理文件中的多个参数循环
【发布时间】:2018-09-08 12:03:59
【问题描述】:

我正在尝试定义一个批处理文件,该文件可以自动更新或检出多个 SVN URL 到特定文件路径中,它将用于设置新用户并使其保持最新状态。此时,这是一个通用批处理文件问题,而不是 SVN 或 TortoiseSVN 问题。问题是如何将我多次复制和粘贴的内容放入一个循环中,我可以将两个参数输入其中。

该过程是重复的,并且需要两个变量(一个 URL 和一个本地文件路径),因此它非常适合循环,但每个 URL 和文件路径都是唯一的,所以我不得不将它们复制并粘贴下来使维护变得困难。
我在 FOR %%A IN ( x x x x ) DO START xxx 示例中为多个文件路径工作,这是我从堆栈溢出搜索中获得的,我在最后注释掉了这就是当我决定希望这是一个自动更新和自动结帐批处理时的变化.我似乎无法让它适用于多个变量,因为该示例只有一个。

目标是拥有一个独立的批处理文件,我不必提供参数或拥有多个批处理文件。环境是 Windows 10。

与原始问题无关:另外,我发布此内容是为了感谢我已经看过的其他帖子。我喜欢多线程的“开始”命令。我不知道如何让 Tortoiseproc 只为我进行结帐,现在它只是打开一个窗口,因此如果未安装 svn.exe,则回显让用户点击确定。我对 .exe 检查的路径进行了硬编码,因为我没有时间尝试“where”命令,而且错误级别检查看起来很笨拙。我让这个批处理文件按原样工作,然后让它通用,如果这破坏了任何东西,我很抱歉。关于如何让语法突出显示正确显示在帖子中的任何 cmets(我读到它应该在标签中选择它,但我尝试了其他语言说明符,但它似乎没有选择它,所以我会看看在我发帖后发生)让我知道。

@echo off 
setlocal
REM This batch file can be used to perform the initial checkout if needed and update svn working copys automatically.
REM It automatically detects a lack of TortoiseSVN.  It has a workaround for if SVN commandline is not installed.
REM If at least TortoiseSVN is installed it automatically detects if the working copy does not exist and performs a checkout.
REM If at least TortoiseSVN is installed it automatically updates already existing working copies.
REM You can automate it via task scheduler.  Ex: Upon lock if network is connected and user is logged in; and/or daily in the morning.
REM TODO: The templates folder has trouble upon initial checkout cleaning out the old normal.dotm file because it already exists.  Probably add hard cleanup.

if not exist "C:\Program Files\TortoiseSVN\bin\TortoiseProc.exe" (
    echo Install TortoiseSVN with command line option
    pause
    exit
) else (
    if not exist "C:\Program Files\TortoiseSVN\bin\svn.exe" (
    echo Proceeding without SVN commandline option.
    echo Hit ok when TortoiseSVN checkout windows open.
    pause
    )
)
REM if everything is good then proceed on!

REM Everyone
SET REPO1_URLDIR=https://REPO1
SET REPO1_PATHDIR=C:\Users\Public\Documents\REPO1

SET REPO2_URLDIR=https://REPO2
SET REPO2_PATHDIR=%appdata%\Microsoft\Templates\

REM designers:
SET REPO3_URLDIR=https://REPO3
SET REPO3_PATHDIR=C:\Users\Public\Documents\REPO3

SET REPO4_URLDIR=https://REPO4
SET REPO4_PATHDIR=C:\Users\Public\Documents\REPO4

REM Optional:
SET REPO5_URLDIR=https://REPO5
SET REPO5_PATHDIR=C:\Users\Public\Documents\REPO5

SET REPO6_URLDIR=https://REPO6
SET REPO6_PATHDIR=C:\Users\Public\Documents\REPO6

REM check if folder exists
if NOT exist "%REPO1_PATHDIR%" (
    rem file doesn't exist.  Create and checkout
    ECHO missing "%REPO1_PATHDIR%" beginning download
    if exist "C:\Program Files\TortoiseSVN\bin\svn.exe" ( 
        START svn checkout %REPO1_URLDIR% %REPO1_PATHDIR%
    ) else ( 
        START TortoiseProc.exe /command:checkout /path:%REPO1_PATHDIR% /url:"%REPO1_URLDIR%" 
    )
) else ( START TortoiseProc.exe /command:update /path:%REPO1_PATHDIR% /closeonend:3 )

if NOT exist "%REPO2_PATHDIR%\blank.potx" (
    rem file doesn't exist.  Create and checkout
    ECHO missing "%REPO2_PATHDIR%" beginning download
    if exist "C:\Program Files\TortoiseSVN\bin\svn.exe" (
        START svn checkout %REPO2_URLDIR% %REPO2_PATHDIR% 
    ) else ( 
        START TortoiseProc.exe /command:checkout /path:%REPO2_PATHDIR% /url:"%REPO2_URLDIR%" 
    )
) else ( START TortoiseProc.exe /command:update /path:%REPO2_PATHDIR% /closeonend:3 )

if NOT exist "%REPO3_PATHDIR%" (
    rem file doesn't exist.  Create and checkout
    ECHO missing "%REPO3_PATHDIR%" beginning download
    if exist "C:\Program Files\TortoiseSVN\bin\svn.exe" ( 
        START svn checkout %REPO3_URLDIR% %REPO3_PATHDIR%
    ) else (
        START TortoiseProc.exe /command:checkout /path:%REPO3_PATHDIR% /url:"%REPO3_URLDIR%"
    )
) else ( START TortoiseProc.exe /command:update /path:%REPO3_PATHDIR% /closeonend:3 )

if NOT exist "%REPO4_PATHDIR%" (
    rem file doesn't exist.  Create and checkout
    ECHO missing "%REPO4_PATHDIR%" beginning download
    if exist "C:\Program Files\TortoiseSVN\bin\svn.exe" ( 
        START svn checkout %REPO4_URLDIR% %REPO4_PATHDIR%
    ) else ( 
        START TortoiseProc.exe /command:checkout /path:%REPO4_PATHDIR% /url:"%REPO4_URLDIR%"
    )
) else ( START TortoiseProc.exe /command:update /path:%REPO4_PATHDIR% /closeonend:3 )

if NOT exist "%REPO5_PATHDIR%" (
    rem file doesn't exist.  Create and checkout
    ECHO missing "%REPO5_PATHDIR%" beginning download
    if exist "C:\Program Files\TortoiseSVN\bin\svn.exe" ( 
        START svn checkout %REPO5_URLDIR% %REPO5_PATHDIR%
    ) else ( 
        START TortoiseProc.exe /command:checkout /path:%REPO5_PATHDIR% /url:"%REPO5_URLDIR%"
    )
) else ( START TortoiseProc.exe /command:update /path:%REPO5_PATHDIR% /closeonend:3 )

if NOT exist "%REPO6_PATHDIR%" (
    rem file doesn't exist.  Create and checkout
    ECHO missing "%REPO6_PATHDIR%" beginning download
    if exist "C:\Program Files\TortoiseSVN\bin\svn.exe" ( 
        START svn checkout %REPO6_URLDIR% %REPO6_PATHDIR%
    ) else ( 
        START TortoiseProc.exe /command:checkout /path:%REPO6_PATHDIR% /url:"%REPO6_URLDIR%"
    )
) else ( START TortoiseProc.exe /command:update /path:%REPO6_PATHDIR% /closeonend:3 )


REM update only:

REM FOR %%A IN (
REM "%REPO1_PATHDIR%"
REM "%REPO2_PATHDIR%"
REM "%REPO3_PATHDIR%"
REM "%REPO4_PATHDIR%"
REM "%REPO5_PATHDIR%"
REM "%REPO6_PATHDIR%"
REM ) DO START TortoiseProc.exe /command:update /path:%%A /closeonend:3

REM • The "FOR %%A" loop will contain, obviously, paths to the projects you want to update.
REM • The "START" bit means "START asynchronously, ie don't wait for end of previous task to launch next one" so that all the Update windows will pop up simultaneously.
REM • Use the "/closeonend:0" to test it first. Means, "don't close the Update window once it's done", so you can actually see what has been updated.
REM There you go. You can even put this .bat file in your STARTup folder to get things updated when you turn your computer on.
REM
REM To close the progress dialog at the end of a command automatically without using the permanent setting you can pass the /closeonend parameter.
REM • /closeonend:0 don't close the dialog automatically
REM • /closeonend:1 auto close if no errors
REM • /closeonend:2 auto close if no errors and conflicts
REM • /closeonend:3 auto close if no errors, conflicts and merges
REM To close the progress dialog for local operations if there were no errors or conflicts, pass the /closeforlocal parameter.

【问题讨论】:

  • 我建议在单个环境变量中定义每个存储库和用户文件夹对,使用| 作为分隔符,这是路径中的无效字符,即set "REPO1=https://REPO1|C:\Users\Public\Documents\REPO1"。然后使用处理set REPO 的输出的FOR 循环,即for /F "tokens=2,3 delims==|" %%I in ('set REPO 2^>nul') do call :ProcessRepo "%%I" "%%J"。此代码在以:ProcessRepo 开头的行之后调用代码作为子例程,第一个参数是存储库 url,第二个参数是用户目录路径。在 cmd 窗口中运行 call /? 寻求帮助。

标签: batch-file svn tortoisesvn batch-processing


【解决方案1】:

您重复的代码块具有以下形式:

if NOT exist _REPO_N_PATH_ (
    rem file doesn't exist.  Create and checkout
    ECHO missing _REPO_N_PATH_ beginning download
    if exist _SVN_PATH_ ( 
        START svn checkout _REPO_N_URL_ _REPO_N_PATH_
    ) else ( 
        START TortoiseProc.exe /command:checkout /path:_REPO_N_PATH_ /url:_REPO_N_URL_
    )
) else ( START TortoiseProc.exe /command:update /path:_REPO_N_PATH_ /closeonend:3 )

我计算了三个参数:1) Repo 路径,2) SVN 可执行路径(尽管这可以保持不变)和 3) repo URL,还有一种特殊情况是使用特定文件名来测试因为它的存在,所以添加第四个可选参数。

编写一个子程序并调用它:

@setlocal ENABLEEXTENSIONS
@rem @set prompt=$G

@rem You can add a search for svn later.
@set _SVN_Path="C:\Program Files\TortoiseSVN\bin\svn.exe"

@call :Action C:\Users\Public\Documents\REPO1 %_SVN_Path% https://REPO1
@call :Action "%appdata%\Microsoft\Templates" %_SVN_Path% https://REPO2 blank.potx
@call :Action "C:\Users\Public\Documents\REPO3" %_SVN_Path% https://REPO3
@rem Etc...
@exit /b 0

@REM Action takes three parameters:
@REM  %%1 is the repo path.
@REM  %%2 is the path to the SVN executable.
@REM  %%3 is the papth to the URI.
@REM  %%4 is optional file name to look for rather than just the directory.
:Action
@if NOT exist %1\%4 (
    @rem file doesn't exist.  Create and checkout
    @ECHO missing %1 beginning download
    @if exist %2 (
        @START svn checkout %3 %1
    ) else (
        @START TortoiseProc.exe /command:checkout /path:%1 /url:%3
    )
) else ( @START TortoiseProc.exe /command:update /path:%1 /closeonend:3 )

以上内容未经测试,但如果我有任何错误,调试起来应该不会太难。只需在测试时删除您希望在输出中看到的任何行前面的 @ 符号即可。

【讨论】:

  • 哦,我现在明白了。与其说是一个“循环”,不如说它在某种程度上变得“功能化”。我喜欢带参数的调用以及最后允许可选参数的方式,以涵盖我之前对古怪文件存在检查的评论。我认为创建 %_SVN_Path% 变量可能是一个好主意,但由于它只在一个地方使用,所以没有它可能没问题,就像你说的那样。我会尝试实现这个概念,看看它是否能很快奏效,除非有人抢先一步。
  • 作为后续,我通过调用正确地实现了这一点并且它有效。好吧,它可以在我的计算机上运行,​​但我认为我在第一次使用时在其他计算机上遇到了 SVN 身份验证问题,因为他们没有先进行正常的结帐以保存凭据。但是一旦建立,这个批处理文件可以让您保持最新状态并重新检查可能已删除的任何内容。当我了解更多信息时会更新。
猜你喜欢
  • 2013-10-07
  • 1970-01-01
  • 2019-11-13
  • 1970-01-01
  • 2022-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-13
相关资源
最近更新 更多