【问题标题】:How to return to the original directory after invoking change directory in DOS batch?DOS批量调用更改目录后如何返回原目录?
【发布时间】:2011-10-22 20:13:38
【问题描述】:

我想创建一个批处理文件 batch.bat,它接受 2 个强制参数:

  • %1 表示相对于当前目录的路径。
  • %2 代表一个文件名。

假设当前目录为father\me\

用户可以按如下方式使用该批次:

  • batch child/grandchild log
  • batch ../brother log

batch.bat的职位描述如下。

  1. 移动到%1 目录,
  2. 迭代%1目录中的所有*.tex文件。
  3. 在移动之前将结果保存在目录中。

以下是不完整的代码:

rem batch.bat takes 2 arguments.
cd %1
dir /b *.tex > <original directory>\%2.txt

DOS批量调用更改目录后如何返回原目录?

【问题讨论】:

    标签: batch-file dos


    【解决方案1】:

    如果要返回原始目录,请使用PUSHD 进行第一次更改,然后使用POPD 返回。也就是说,移动到 %1 目录必须通过

    PUSHD %1
    

    而不是 CD %1,返回是用

    POPD
    

    而不是CD在哪里?

    如果您想在更改后访问原始目录,请将其存储在变量中:

    SET ORIGINAL=%CD%
    

    稍后再使用 %ORIGINAL%,例如:

    dir /b *.tex > %original%\%2.txt
    

    【讨论】:

    • +1:另外 PUSHD 用于 CD 到网络连接的驱动器,因为 CD 不允许您这样做。
    • 一年前当我使用批处理并且不得不处理网络驱动器时,该评论在哪里?如果可以的话 +100
    【解决方案2】:

    PUSHD / POPD 绝对是执行此操作的首选方式。但是 SETLOCAL / ENDLOCAL 有一个(未记录的?)功能可以完成同样的事情(除了 SETLOCAL 所做的所有其他事情)。

    如果您在 SETLOCAL 之后更改目录,那么您将在 ENDLOCAL 后返回原始目录。

    cd OriginalLocation
    setlocal
    cd NewLocation
    endlocal
    rem we are back to OriginalLocation
    

    另一件关于 SETLOCAL 的事情 记录在案 - 调用的批处理或 :label 例程中的任何 SETLOCAL 在退出批处理或例程时都会以隐含的 ENDLOCAL 终止。隐式 ENDLOCAL 将像显式 ENDLOCAL 一样返回到原始文件夹。

    cd OriginalLocation
    call :ChangeLocation
    rem - We are back to OriginalLocation because :ChangeLocation did CD after a SETLOCAL
    rem - and there is an implicit ENDLOCAL upon return
    exit /b
    
    :ChangeLocation
    setlocal
    cd NewLocation
    exit /b
    

    我不建议使用 SETLOCAL/ENDLOCAL 代替 PUSHD/POPD。但这是您应该注意的行为。

    回应约翰尼的评论

    当 PUSHD/POPD 和 SETLOCAL/ENDLOCAL 结合使用时,可能会让人感到困惑。 ENDLOCAL 确实清除 PUSHD 堆栈,如下所示:

    setlocal
    cd test
    @cd
    pushd new
    @cd
    endlocal
    @cd
    popd
    @cd
    

    --输出--

    D:\test>setlocal
    
    D:\test>cd test
    D:\test\test
    
    D:\test\test>pushd new
    D:\test\test\new
    
    D:\test\test\new>endlocal
    D:\test
    
    D:\test>popd
    D:\test\test
    

    【讨论】:

    • @johnny - 不正确(至少在我测试的 Win 7 上不正确)。 pushd 堆栈被保留。请参阅我的更新答案。
    • 我的错;我发誓我在发布之前已经反复测试过(因为它看起来确实很奇怪),但是当我完成测试脚本时我删除了它们,现在无法复制我的认为我是看到...脚本或子例程中无法匹配的 pushd/popd 仍然可能是一个问题...
    【解决方案3】:
    set ORIGINAL_DIR=%CD% 
    
    REM #YOUR BATCH LOGIC HERE
    
    chdir /d %ORIGINAL_DIR% 
    

    【讨论】:

      【解决方案4】:

      您总是可以在更改目录之前将 %cd% 设置为变量:

      set current="%cd%"
      cd "C:\Some\Other\Folder"
      cd "%current%"
      

      在大多数情况下,在批处理脚本中使用目录创建变量。如果脚本是半长的,我将在脚本的开头定义我的变量,包括重要的路径、文件、子和/或长命令。

      @ECHO OFF
      REM Variables
      ::Programs
      SET save_attachments=C:\Program Files\APED\Program\save_attachments.vbs
      SET sendemail=C:\Program Files\APED\Program\sendkeys.vbs
      SET tb=C:\Program Files\Mozilla Thunderbird\thunderbird.exe
      SET fox=C:\Program Files\Foxit Software\Foxit Reader\Foxit Reader.exe
      SET spool=C:\WINDOWS\system32\PRNJOBS.vbs
      
      ::Directories
      SET new=C:\Program Files\APED\New
      SET printing=C:\Program Files\APED\Printing
      SET finish=C:\Program Files\APED\Finish
      SET messages=C:\Program Files\APED\Script_Messages
      SET nonpdf=C:\Program Files\APED\NonPDFfiles
      SET errorfiles=C:\Program Files\APED\Error Files
      
      ::Important Files
      SET printlog=C:\Program Files\APED\Script_Messages\PrintLOG.txt
      SET printemail=C:\Program Files\APED\Script_Messages\EmailPrintLOG.txt
      SET errorlog=C:\Program Files\APED\Script_Messages\ErrorLOG.txt
      SET erroremail=C:\Program Files\APED\Script_Messages\EmailErrorLOG.txt
      SET movefiles=C:\Program Files\APED\Script_Messages\MoveFiles.txt
      

      但是,如果 PUSHD 和 POPD 是简短而甜蜜的 imo,则它们是很好的解决方案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多