如何在批处理文件中使用环境变量更改目录?

问题描述 投票:0回答:2

我尝试创建一个小应用程序,使用默认的 Microsoft 排序功能来整理我的文件夹。我使用一个名为

tosort
的变量,在用户输入时应该检查该目录是否存在。

这是我的代码:

echo off
:retry
set /p tosort=Enter the Directory to sort :
chdir "tosort"
if exist %tosort%\ (
    echo "DIRECTORY FOUND"
    )else (
    goto :retry)

但是,每当批处理达到

%tosort%\
时,就会输出错误消息:

c:\ 不是预期的

batch-file cmd directory
2个回答
2
投票

您的代码可能会失败,因为目录路径中有空格,如果路径中有空格,您需要在其周围使用双引号。

"%tosort%\"

我对游览代码进行了一些重构,以使其更具可读性和利用功能,包括主功能。

通过使用

Call :Label
,我们移动到函数标签,并在函数完成时返回并执行下一行。

这意味着脚本的结尾是

Endlocal
药水。

在脚本中使用

SetLocal
endlocal
是一种很好的做法,这样,如果您从另一个调用其中一个,则一个中生成的更改不会存在于另一个中。 (如果您想返回一些变量,可以将它们放在退出 /b 之前的括号内)

函数最好以

GOTO :EOF
结尾,
:EOF
标签是文件末尾的占位符,因为脚本或函数会被读取到文件末尾。文件末尾的函数可以将其关闭,但最好将其保留并统一声明所有函数。

编辑:因为您可能想检查目录是否存在带有尾随

\
,然后稍后在不带尾随
\
的情况下使用它来执行某些其他命令,并且由于用户可以自己添加尾随
\
,并且可以将路径用双引号
"
本身括起来,我正在修改此内容以进行所有检查。

请注意,

REM
是用于注释脚本的注释命令。

如果将脚本顶部的

ECHO OFF
更改为
ECHO ON
,备注将与正在运行的命令一起打印,您将能够看到脚本的执行位置。

@(SETLOCAL
  echo off
)

Call :Main

( Endlocal
  Exit /b
)

:Main
  REM Call the SetCheckDir Function
   Call :SetCheckDir

 REM Change directory to the path that we found
  chdir "%tosort%"

REM This following line ends the Main Function
Goto :EOF

:SetCheckDir

  REM Check for the path from the user
   SET /p "tosort=Enter the Directory to sort: "

  REM Clear off double qoutes
   SET "TmpVar=%tosort:"=%"

  REM Add Trailing backslash
   IF /I "%TmpVar:~-1%" NEQ "\" SET "TmpVar=%TmpVar%\"

  REM Test if the Directory path is good:
   IF NOT EXIST "%TmpVar%" ( GOTO :SetCheckDir )

  REM Set the original variable to the found path, minus the trailing backslash
   SET "tosort=%TmpVar:~0,-1%"
Goto :EOF


0
投票

问题中发布的代码存在多个问题:

  1. 用户可以根本不输入任何字符串,在这种情况下,环境变量
    tosort
    仍未定义或仍使用批处理文件外部定义的值进行定义。
  2. 命令
    chdir "tosort"
    不引用环境变量的值,这需要使用
    chdir "%tosort%"
  3. 如果当前目录位于不同的驱动器上,则使用
    chdir "%tosort%"
    将无法更改当前目录。使用
    chdir /D "%tosort%"
    可以解决这个问题。
  4. 如果批处理文件的用户输入
  5. UNC
     路径,
    chdir /D "%tosort%" 将会失败。解决方案是启用命令扩展的
    pushd "%tosort%"
    以及匹配的
    popd
    (如果此命令执行成功),将当前目录路径压入堆栈,并将指定的文件夹路径设置为当前目录(如果使用
    "%tosort%"
    引用的文件夹)根本存在。
  6. 批处理文件的用户可以输入一个或多个
    "
    的字符串,在这种情况下,上述所有命令都将无法正确执行。
  7. if exist %tosort%\
    输入的包含空格或这些字符之一的字符串会失败
    &()^=;!+,~<>|
    ,因为执行此命令行时引用的字符串值未用双引号括起来。

所有潜在问题的解决方案是使用以下注释代码:

@echo off
rem Define together with the line above the execution environment completely.
setlocal EnableExtensions DisableDelayedExpansion

:Retry
set "FolderToSort="
set /P "FolderToSort=Enter the directory to sort: "
rem Has the user not input any string at all?
if not defined FolderToSort goto Retry
rem Remove all double quotes from the input string.
set "FolderToSort=%FolderToSort:"=%"
rem Has the user input just double quotes?
if not defined FolderToSort goto Retry

rem Make the directory entered by the user the current directory.
rem The command PUSHD exits with 0 on success and with 1 on failure.
pushd "%FolderToSort%" 2>nul
echo(
if errorlevel 1 (
    echo ERROR: There is no accessible directory:
    echo        "%FolderToSort%"
    echo(
    goto Retry
)
setlocal EnableDelayedExpansion
echo Current directory: !CD!
endlocal
echo(

rem Do something in current directory being the directory entered by the user.
dir

rem Restore the initial current directory.
popd
rem Restore the initial execution environment.
endlocal

可以删除备注(注释)以提高效率,这意味着所有以命令

rem
开头的行。

要了解所使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完整、仔细地阅读每个命令显示的帮助页面。

  • dir /?
  • echo /?
  • endlocal /?
  • goto /?
  • if /?
  • popd /?
  • pushd /?
  • rem /?
  • set /?
  • setlocal /?
© www.soinside.com 2019 - 2024. All rights reserved.