Board logo

标题: 碰到个for和管道命令组合的诡异问题(原因找到,机理未名) [打印本页]

作者: picat     时间: 2007-8-24 17:31    标题: 碰到个for和管道命令组合的诡异问题(原因找到,机理未名)

建了一个脚本,名为JobTime.vbs,代码如下:
Option Explicit
Dim n
Dim intCount

intCount = 2

ReDim strTime(intCount)
ReDim strWeekDay(intCount)
ReDim strDaySerial(intCount)



strTime(0) = FormatDateTime(TimeValue(TimeSerial(Hour(Now),30,0)),vbShortTime)
strWeekDay(0) = WeekdayName(Weekday(Now))
strDaySerial(0) = Now

For n = 0 To intCount-1
        strTime(n+1)=Timevalue(strTime(n))+ TimeSerial(0,30,0)
        strTime(n+1)= FormatDateTime(strTime(n+1),vbShortTime)
        strDaySerial(n+1) = strDaySerial(n) + TimeSerial(0,30,0)
        strWeekDay(n+1) = WeekdayName(Weekday(strDaySerial(n+1)))
        WScript.Echo strWeekday(n) & "," & strTime(n)
next
作用是生成当前整点时间往后的2个时间点,步长为30分钟。
然后用P处理生成2个时间点的任务计划,并且检查是否成功,代码如下:
@echo off

c:

cd\


for /f "tokens=1,2 delims=," %%i in ('cscript //nologo JobTime.vbs') do (AT %%j /every:%%i "c:\job.bat")

@rem 检查成功与否

for /f "tokens=1,2 delims=," %%i in ('cscript //nologo JobTime.vbs') do (
AT ^|find /I "C:\job.bat" ^|find "%%i" ^|find "%%j"
)

pause
前面没有任何问题,问题就在检查成功与否的这一个for循环中,运行到这一步就提示:
无效的命令。

AT 命令安排在特定日期和时间运行命令和程序。
要使用 AT 命令,计划服务必须已在运行中。

AT [\\computername] [ [id] [/DELETE] | /DELETE [/YES]]
AT [\\computername] time [/INTERACTIVE]
    [ /EVERY:date[,...] | /NEXT:date[,...]] "command"
以下省略......
但是我把echo off 改成 echo on,发现它生成的命令都是正确的,比如:
C:\>(AT |find /I "C:\job.bat" |find "星期五" |find "18:00" )
无效的命令。

AT 命令安排在特定日期和时间运行命令和程序。
要使用 AT 命令,计划服务必须已在运行中。
以下省略......
我把它们复制(AT |find /I "C:\job.bat" |find "星期五" |find "18:00" )下来单独运行也没有问题,
如:
C:\>(AT |find /I "C:\job.bat" |find "星期五" |find "18:00" )
       18   每月执行日期: 星期五    下午 18:00    c:\job.bat
能够正确的找到,百思不得其解。

把AT换成dir命令(比如dir ^|find "C:\test.bat"),倒是可以运行,但是得到的结果格式和预期的也不一样。预期的结果应该是符合find条件的一行,但实际运行下来的结果是这样的:
C:\>for /F "tokens=1,2 delims=," %i in ('cscript //nologo JobTime.vbs') do (dir
|find "C:\test.bat" )

C:\>(dir |find "C:\test.bat" )
驱动器 C 中的卷是 SYSTEM
卷的序列号是 8072-864F

C:\ 的目录


C:\ 的目录

2007-08-24  17:27                  296 test.bat
               1 个文件            296 字节
               0 个目录 10,650,035,200 可用字节
这个是不是又跟dos的某个机制有关的?希望大家给点意见,谢谢!

[ Last edited by picat on 2007-8-24 at 10:14 PM ]
作者: picat     时间: 2007-8-24 18:03
补充一下,我的环境是windows XP SP2 Proffessional中文版,cmd模式

然后我换了个方法,把检查的语句顺序换了一下:
@echo on


for /f "tokens=3,5,6 delims= " %%i in ('AT ^|find /I "c:\job.bat"') do (cscript //nologo JobTime.vbs ^|find "%%j" ^|find "%%i")


pause
诡异的事情又来了,得到的结果居然是这样的:
C:\>for /F "tokens=3,5,6 delims= " %i in ('AT |find /I "c:\job.bat"') do (cscrip
t //nologo JobTime.vbs |find "%j" |find "%i" )

C:\>(cscript //nologo JobTime.vbs |find "17:30" |find "星期五" )
星期五,17:30
星期五,18:00

C:\>(cscript //nologo JobTime.vbs |find "18:00" |find "星期五" )
星期五,17:30
星期五,18:00

C:\>pause
请按任意键继续 . . .
命令都对,也都执行了,但是出来的结果却是把生成的2个时间的任务都找出来了,似乎|find没有起到作用......

[ Last edited by picat on 2007-8-24 at 06:05 PM ]
作者: slore     时间: 2007-8-24 18:30
@echo off
c:
cd\
for /f "tokens=1,2 delims=," %%i in ('cscript //nologo JobTime.vbs') do (
AT %%j /every:%%i "c:\job.bat"
AT |find /I "C:\job.bat" |find "%%i" |find "%%j"
)
pause

你看看?

你的VBS有问题哦~如果现在是23点,你设置数量是2个点得到的第2个 0:00你看是星期几?
作者: picat     时间: 2007-8-24 21:23
slore你说的对,我改了一下:
Option Explicit
Dim n
Dim intCount

intCount = 2

ReDim strTime(intCount)
ReDim strWeekDay(intCount)
ReDim strDaySerial(intCount)

strTime(0) = FormatDateTime(TimeValue(TimeSerial(Hour(Now),0,0)),vbShortTime)
strWeekDay(0) = WeekdayName(Weekday(Now))
strDaySerial(0) = Now

For n = 1 To intCount
        strTime(n)=Timevalue(strTime(n-1))+ TimeSerial(0,30,0)
        strTime(n)= FormatDateTime(strTime(n),vbShortTime)
        strDaySerial(n) = strDaySerial(n-1) + TimeSerial(0,30,0)
        strWeekDay(n) = WeekdayName(Weekday(strDaySerial(n)))
        WScript.Echo strWeekday(n) & "," & strTime(n)
next
不过这个貌似下标越界的代码居然可以正常运行...,今天尽碰到怪事了。
作者: picat     时间: 2007-8-24 21:28
还有你上面的P代码我也测试过了,还是同样的问题:
无效的命令。

AT 命令安排在特定日期和时间运行命令和程序。
要使用 AT 命令,计划服务必须已在运行中。
以下省略......
作者: slore     时间: 2007-8-24 21:29
哪里下标越界了?
作者: picat     时间: 2007-8-24 21:34


  Quote:
Originally posted by slore at 2007-8-24 21:29:
哪里下标越界了?

在这儿:
For n = 1 To intCount  --假设intcount=16

我前面
ReDim strTime(intCount)
ReDim strWeekDay(intCount)
ReDim strDaySerial(intCount)

那么下标应该是从0-15吧,可我WScript.Echo strWeekday(n) & "," & strTime(n)这个n从1-16

[ Last edited by picat on 2007-8-24 at 09:55 PM ]
作者: slore     时间: 2007-8-24 21:36
intcount=16

数组里写16不是个数,是上界……没有使用To,下界用默认的0开始……
所以是0到16

1-16属于0-16的范围……
作者: slore     时间: 2007-8-24 21:38
=。=说到VB去了……VBS里没有To……只能从0开始……
作者: picat     时间: 2007-8-24 21:41


  Quote:
Originally posted by slore at 2007-8-24 21:36:
intcount=16

数组里写16不是个数,是上界……没有使用To,下界用默认的0开始……
所以是0到16

1-16属于0-16的范围……

晕了,一直以为dim里的数字是个数...,好像是跟以前学的哪个语言搞混了...
作者: picat     时间: 2007-8-24 21:44
slore,你觉得上面的P代码,可能的问题在哪里啊?感觉上跟|find有关,但又只在说不出问题在哪里.......
作者: slore     时间: 2007-8-24 21:54
P我已经给你改过了啊……你运行我写的代码看看啊
作者: picat     时间: 2007-8-24 21:59
不好意思,刚才运行确实可以了,之前一次不知道哪里搞错了。但我觉得你的P代码跟我的没有实质性的区别啊,能告诉我什么原因吗?
作者: picat     时间: 2007-8-24 22:06
发现了,问题在转义字符^上,我把原先的P代码改成:
@echo off

c:

cd\


for /f "tokens=1,2 delims=," %%i in ('cscript //nologo JobTime.vbs') do (AT %%j /every:%%i "c:\job.bat")

@rem 检查成功与否

for /f "tokens=1,2 delims=," %%i in ('cscript //nologo JobTime.vbs') do (
AT |find /I "C:\job.bat" |find "%%i" |find "%%j"
)

pause
去掉里面的^就可以正常运行了......
但是P代码里用到管道|不是需要^来转义的?.......晕死。这应该又是DOS的某个特殊点......,而且有^和没有^生成的命令都是一样的(至少看起来一样),但一个正常运行一个就不行.......

[ Last edited by picat on 2007-8-24 at 10:08 PM ]
作者: slore     时间: 2007-8-24 22:25
你是要当字符串麽?转义?
你是要执行呀……转义干什么
作者: picat     时间: 2007-8-24 22:34
这个是很久之前看过的文章里提到的,当时也没深究,看来要搜索些关于转义的帖子来看看了,谢谢slore不厌其烦的解释~~
作者: picat     时间: 2007-8-24 22:56
找到了

  Quote:
  使用 at 的已经计划的命令作为后台程序运行。运行结果不会显示在计算机上。要将输出重定向到文件,请使用重定向符号 (> )。如果将输出重定向到文件,则不论是在命令行还是在批处理文件中使用 at,都需要在重定向符号之前使用转义符 (^)。例如,要重定向输出到 Output.text 文件,则要键入:

  at 14:45 c:\test.bat ^>c:\output.txt

时间久了,记忆上的偏差让我一直认为在P代码中管道符需要^来转义......