For loop 如果不是从cmd行运行,则该命令的语法不正确

For loop 如果不是从cmd行运行,则该命令的语法不正确,for-loop,syntax,batch-file,cmd,task,For Loop,Syntax,Batch File,Cmd,Task,我有一个批处理文件,如果我从命令提示符运行它,它可以正常运行,但是如果它是从任务调度器或通过资源管理器调用的,则会抛出一个错误。似乎FOR逻辑出现语法错误 @echo off del mic_car*.txt ftp -i -s:car_ftp_script.txt pause for /F %%I in ('dir /b/os mic_car*.txt') do ( echo %%I pause set tempfile=%%I if exist %tempfile%

我有一个批处理文件,如果我从命令提示符运行它,它可以正常运行,但是如果它是从任务调度器或通过资源管理器调用的,则会抛出一个错误。似乎FOR逻辑出现语法错误

@echo off

del mic_car*.txt

ftp -i -s:car_ftp_script.txt

pause

for /F %%I in ('dir /b/os mic_car*.txt') do (
  echo %%I
  pause
  set tempfile=%%I
  if exist %tempfile% (
    del car_report.txt
    ren %tempfile% car_report.txt
  ) 
)

del mic_car*.txt
copy /y car_report.txt ..\car_report.txt

pause

如果我从资源管理器或任务调度器运行此命令,我会看到文件通过FTP传输,后跟语法错误。如果我通过命令行运行它,我会看到正在处理的每个文件的回音,并且最大的文件会复制到更高级别的目录。

您使用的是什么版本的Windows

我已经更改了脚本,用从目录列表中提取的数据调用子例程

@echo off

del mic_car*.txt

ftp -i -s:car_ftp_script.txt

pause

for /F %%I in ('dir /b/os mic_car*.txt') do call :blue %%I
goto exit

:blue
  echo -- processing %1 -------------
  pause
  set tempfile=%1
  if exist %tempfile% (
    del car_report.txt
    ren %tempfile% car_report.txt
    echo -- renamed %tempfile% to car_report.txt -------------
  ) 


del mic_car*.txt
copy /y car_report.txt ..\car_report.txt
echo -- finished %1 -------------
pause

goto :eof

:exit

<> P>在Windows资源管理器和调度器之间存在默认目录的差异,因此,您应该考虑使用显式路径来找到您的目标文件的文件和目录。例如delc:\carfiles\mi_car*.txt等。

这些行是导致错误的原因:

set tempfile=%%I
if exist %tempfile% (
%
-变量在解析时展开,即当解释器解析命令(在本例中为for循环)时。此时,循环变量没有值,因此
%tempfile%
为空,从而导致错误

您需要启用延迟扩展并使用
-循环内的变量。当循环变量包含实际值时,这些变量在运行时展开

setlocal EnableDelayedExpansion

for /F %%I in ('dir /b/os mic_car*.txt') do (
  echo %%I
  pause
  set tempfile=%%I
  if exist !tempfile! (
    del car_report.txt
    ren !tempfile! car_report.txt
  ) 
)

您的代码无法正常工作,即使是从命令行

您的问题是设置了
tempfile
并从同一代码块中扩展了
%tempfile%
。解析该行时,该值将展开,并且FOR语句的所有行都将在一次传递中解析。因此,IF和REN语句看到了在进入循环之前存在的值

当未定义
tempfile
时,代码将失败并出现语法错误。扩展后,IF语句变得无效:
IF-exist(…
),因此出现错误

您认为它可以从命令行运行的原因是,您可能只运行了一次代码,但它失败了,但完成后,设置了
tempfile
变量,因此下次运行脚本时,脚本将显示为运行正常

通常,我建议使用延迟扩展来启用设置和扩展循环中的变量。但您根本没有任何理由使用
tempfile
,只需直接使用FOR变量即可

@echo off

del mic_car*.txt

ftp -i -s:car_ftp_script.txt

for /F %%I in ('dir /b/os mic_car*.txt') do (
  echo %%I
  if exist "%%I" (
    del car_report.txt
    ren "%%I" car_report.txt
  ) 
)

del mic_car*.txt
copy /y car_report.txt ..\car_report.txt

pause
实际上,我不明白为什么需要IF,因为FOR循环只返回现有文件。而且所有mic_car*.txt文件都将被重命名为car_report.txt(最后一个文件获胜),所以不需要使用最终的DEL命令

您可以使用MOVE将DEL和REN命令组合成一个命令

@echo off

del mic_car*.txt

ftp -i -s:car_ftp_script.txt

for /F %%I in ('dir /b/os mic_car*.txt') do (
  echo %%I
  move /y "%%I" car_report.txt >nul
)

copy /y car_report.txt ..\car_report.txt

pause

好的,你看到了!它一定一直在工作,因为它已经运行了两次…我从来没有对批处理文件做过很多工作,这些信息非常有用!谢谢你的建议和解释。