【问题标题】:Batch file calls another batch when i execute it directly, but not when scheduled批处理文件在我直接执行时调用另一个批处理,但不是在计划时
【发布时间】:2021-07-04 00:38:14
【问题描述】:

我有这个 Batchscript(简化,将所有 REM-cmets 和 echo-outputs 删除到一个 txt 文件):

SET DateTime=%date:~0% - %time:~0,8% Uhr
DEL D:\_script_autodel\_folderlist.txt
dir D:\Interfaces /s /b /a:d /o:n >> D:\_script_autodel\_folderlist.txt
for /F "tokens=*" %%A in (D:\_script_autodel\_folderlist.txt) do DeleteOldFiles.bat %%A

前3行执行有效,但第4行没有执行,或者至少作为计划任务运行时没有进入DeleteOldFiles.bat。

当我直接在 cmd 窗口中运行脚本时,DeleteOldFiles.bat 脚本被正确调用。

【问题讨论】:

  • 我将 dir 输出更改为: for /F "tokens=*" %%A in (D:_script_autodel_folderlist.txt) do DeleteOldFiles.bat %%A & echo %%A >> D: _script_autodel\log.txt 尽管如此,它仍然不起作用......但我注意到一些有趣的事情 - 也许这可以帮助找到解决方案: - 我将第 4 行更改如下: for /F "tokens=*" %%A在 (D:_script_autodel_folderlist.txt) 中执行 DeleteOldFiles.bat %%A & echo %%A >> D:_script_autodel\log.txt - 当我将它作为计划任务运行时,它会将我打印出整个数组。当我直接运行它时,它应该一行一行地运行
  • 您在没有路径的情况下调用DeleteOldFiles.bat,然后假定它位于工作目录中,这将是c:\windows\system32,显然找不到它。成功:for /F "tokens=*" %%A in (D:\_script_autodel\_folderlist.txt) do call "D:\_script_autodel\DeleteOldFiles.bat" %%A

标签: shell loops batch-file scheduled-tasks


【解决方案1】:

首先,我们将逐行检查您的代码:

SET DateTime=%date:~0% - %time:~0,8% Uhr

以上行有问题。首先它没有使用正确的语法set "var=string value"。然后它不必要地扩展了%DATE% 变量字符串,因为~0 是包括第一个字符在内的所有内容。它还打印%TIME% 变量值字符串的前八个字符,这是未知的,因为它的格式是用户、PC、语言环境和语言可配置的字符串值。它还在我看来是一个奇怪的原因,将字符串 Uhr 后缀到末尾。我希望仅当您包含小时或按已知时间表运行小时和分钟而不是前八个字符时才包含它

DEL D:\_script_autodel\_folderlist.txt

首先,为了获得最佳实践,文件路径应始终用双引号引起来。它不会首先检查文件是否存在,因此如果不存在,可能会生成错误消息。它也没有真正的目的,因为如果它不存在,下一行将创建它,如果存在,它将覆盖它。

dir D:\Interfaces /s /b /a:d /o:n >_folderlist.txt

此行再次不使用双引号作为最佳实践,并创建一个文件,该文件仅在下一个命令行中使用时需要。它没有其他用途,所以我们应该将其合并到下一行,而不是不必要地创建文件。

for /F "tokens=*" %%A in (D:\_script_autodel\_folderlist.txt) do DeleteOldFiles.bat %%A

上面的行有一个小问题,再次是最佳实践双引号:For /F "UseBackQ Tokens=*" %%A In ("D:\_script_autodel\_folderlist.txt") Do …,还有一个主要问题,即您将每一行逐行传递给另一个批处理文件。因此,目的是在处理完每个脚本后返回此脚本,因此您应该使用Call 命令。

因此,您只需要一行:

@For /F "Tokens=*" %%G In ('Dir "D:\Interfaces" /A:D /B /O:N /S" 2^>NUL') Do @Call "%~dp0DeleteOldFiles.bat" "%%G"

请注意,您的代码没有定义当前工作目录,这是您脚本中的一个主要问题。从任务调度程序运行时,当前工作目录不太可能与您自己调用它时相同。因此,我使用了您的批处理文件的完整路径。在这种情况下,我使用%~dp0 来表示它的相同位置,作为正在运行的批处理文件。请根据需要用另一个绝对路径替换它,例如D:\_script_autodel\DeleteOldFiles.bat。如果它在其他地方。

【讨论】:

    【解决方案2】:

    从任务计划程序启动时,您的工作目录将为c:\windows\system32。您没有指定要尝试运行的 batch-file 的路径,因此找不到它。您需要指定文件的路径:

    for /F "tokens=*" %%A in (D:\_script_autodel\_folderlist.txt) do call "D:\_script_autodel\DeleteOldFiles.bat" %%A
    

    但是,您可以使用 pushd. You can also skip the deletion of the _folderlist.txtfile if you use single redirect>` 跳过在任何地方写入路径,因为这将在每次启动脚本时替换内容。

    @echo off
    set "DateTime=%date:~0% - %time:~0,8% Uhr"
    pushd "D:\_script_autodel"
    (dir "D:\Interfaces" /s /b /a:d /o:n)>"_folderlist.txt"
    for /F "tokens=*" %%A in (_folderlist.txt) do call DeleteOldFiles.bat "%%~A"
    

    【讨论】:

      【解决方案3】:

      代码的第三行将文件“_folderlist.txt”放在当前目录中。 其他行使用路径“D:_script_autodel” 如果当前路径不同,第四行将无法找到该文件。

      解决方案:更改第三行以包含文件的完整路径。

      【讨论】:

      • 这不是问题。该脚本在 D:_script_autodel 内部被调用,并且文件 folderlist.txt 正在被删除并重建......我还是尝试过,但这并不能解决问题。
      • 任务计划历史抛出成功消息或返回码0
      • OJ 是对的。当您手动运行脚本时,您可能位于正确的文件夹中。当您将其作为计划任务运行时检查工作文件夹(这不是我猜您认为的那样)将dir 输出明确重定向到"D:\_script_autodel\_folderlist.txt"
      猜你喜欢
      • 1970-01-01
      • 2015-02-23
      • 2013-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-27
      • 1970-01-01
      • 2011-02-04
      相关资源
      最近更新 更多