如果脚本正在由任务调度程序运行,我如何捕获它的输出?
Posted
技术标签:
【中文标题】如果脚本正在由任务调度程序运行,我如何捕获它的输出?【英文标题】:How do I capture the output of a script if it is being ran by the task scheduler? 【发布时间】:2012-01-29 12:38:50 【问题描述】:使用 Windows Server 2008,如何捕获正在使用 Windows 任务调度程序运行的脚本的输出?
我正在测试一个相当长的自定义打印批处理脚本,出于调试目的,我希望每晚查看它的所有输出。
【问题讨论】:
有时,这不起作用,即没有生成日志文件。导致这种情况的一种情况是任务根本没有启动,因为 Windows 错误地认为它仍在运行。您可以通过查看任务历史来跟踪它(任务属性中的历史选项卡 - 信息可能需要几秒钟才能显示) 【参考方案1】:试试这个作为任务计划程序中的命令字符串:
cmd /c yourscript.cmd > logall.txt
【讨论】:
此外,如果您有空格,请使用cmd /c "path with spaces/command.cmd > file.txt"
。来自Ivan's answer 的2>&1
也在引号内。
需要使用双引号才能让我的工作:***.com/a/6378038/1747983cmd /c ""C:\temp\My test dir\something 123\myTool.exe" > Tilo_log.txt 2>&1"
现在我在运行任务时会显示一个命令窗口。如何预防?
@Chris 查看这个答案:***.com/a/52206695/184839
您会错过错误而无需通过添加2>&1
重定向stderr,如本页另一个答案***.com/a/23808212/727345 中所述【参考方案2】:
为了补充@user2744787 的回答,这里有一个屏幕截图,展示了如何在计划任务中使用cmd
和参数:
程序/脚本:cmd
添加参数:/c run_with_default_port.bat > IMQuantWebServices.log
【讨论】:
您似乎正在通过计划任务启动服务。如果这应该是在后台持续运行的服务,请查看 NSSM 作为替代方案。它将任何命令作为 Windows 服务运行,并在失败后处理重启等。 哇,终于。这是安排 cmd 作业的确切过程。【参考方案3】:使用 stderr(大部分错误都在其中):
cmd /c yourscript.cmd > logall.txt 2>&1
【讨论】:
这改进了 OP 请求记录以进行调试的可接受答案,因为它也会记录错误。【参考方案4】:>>
将附加日志文件,而不是每次都覆盖它。 2>&1
也会将错误发送到您的日志文件。
cmd /c YourProgram.exe >> log.txt 2>&1
【讨论】:
【参考方案5】:你可以有一个调用 yourscript.cmd 的 debug.cmd
yourscript.cmd > logall.txt
你安排 debug.cmd 而不是 yourscript.cmd
【讨论】:
【参考方案6】:使用cmd.exe
命令处理器构建一个带时间戳的文件名来记录计划任务的输出
要建立在其他人的答案的基础上,您可能希望创建一个输出文件,该文件的名称中嵌入了日期和/或时间。您可以使用cmd.exe
命令处理器为您执行此操作。
注意:此技术采用内部 Windows 环境变量的字符串输出,并根据字符位置对它们进行切片。因此,以下示例中提供的确切值对于您使用的 Windows 区域可能不正确。此外,对于某些区域设置,日期或时间的某些组件可能会在其值小于 10 时在构造的文件名中引入一个空格。为了缓解此问题,请用引号将您的文件名括起来,以便文件中的任何意外空格name 不会破坏您正在构建的命令行。试验并找出最适合您情况的方法。
请注意,PowerShell
比 cmd.exe
更强大。它更强大的一种方式是它可以处理不同的 Windows 区域。但这个答案是关于使用cmd.exe
解决这个问题,而不是PowerShell
,所以我们继续。
使用cmd.exe
您可以通过切片内部环境变量%date%
和%time%
来访问日期和时间的不同组成部分,如下所示(同样,确切的切片值取决于在窗户):
%date:~10,4%
月份(2位数):%date:~4,2%
日期(2 位数):%date:~7,2%
小时(2 位数):%time:~0,2%
分钟(2 位数):%time:~3,2%
第二个(2 位):%time:~6,2%
假设您希望使用以下日期/时间格式命名您的日志文件:“Log_[yyyyMMdd]_[hhmmss].txt
”。您将使用以下内容:
Log_%date:~10,4%%date:~4,2%%date:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.txt
要对此进行测试,请运行以下命令行:
cmd.exe /c echo "Log_%date:~10,4%%date:~4,2%%date:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.txt"
综上所述,要将 stdout
和 stderr
从脚本重定向到以当前日期和时间命名的日志文件,可以使用以下命令作为命令行:
cmd /c YourProgram.cmd > "Log_%date:~10,4%%date:~4,2%%date:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.txt" 2>&1
注意在文件名周围使用引号来处理日期或时间组件可能引入空格字符的实例。
在我的例子中,如果当前日期/时间是 10/05/2017 9:05:34 AM,则上述命令行将生成以下内容:
cmd /c YourProgram.cmd > "Log_20171005_ 90534.txt" 2>&1
【讨论】:
不到 10 小时没有前导零:/不确定如何修复,但至少引用文件名【参考方案7】:您可以在要输出的行上写入日志文件,如下所示:
@echo off
echo Debugging started >C:\logfile.txt
echo More stuff
echo Debugging stuff >>C:\logfile.txt
echo Hope this helps! >>C:\logfile.txt
如果您不想浏览所有内容,则可以通过这种方式选择要输出的命令,只需获取您需要查看的内容即可。 >
会将其输出到指定的文件(如果文件不存在则创建文件,如果存在则覆盖它)。 >>
将追加到指定的文件(如果文件不存在则创建文件,如果存在则追加到内容)。
【讨论】:
【参考方案8】:示例如何运行程序并将stdout和stderr写入带有时间戳的文件:
cmd /c ""C:\Program Files (x86)\program.exe" -param fooo >> "c:\dir space\Log_%date:~10,4%%date:~4,2%%date:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.txt" 2>&1"
关键部分是对cmd /c
后面的整个部分进行双引号,并在其中照常使用双引号。另请注意,日期取决于区域设置,此示例使用美国区域设置。
【讨论】:
【参考方案9】:这个 sn-p 使用 wmic.exe 来构建日期字符串。它不受语言环境设置的影响
rem DATE as YYYY-MM-DD via WMIC.EXE
for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set datetime=%%I
set RDATE=%datetime:~0,4%-%datetime:~4,2%-%datetime:~6,2%
【讨论】:
【参考方案10】:结合其他答案,每个答案都有一些有用的提示,但没有一个能抓住每一个细微差别:
在任务计划程序中 > 操作:
操作:Start a program
程序/脚本:cmd
添加参数:/c ""C:\my path\my task.cmd" >> "C:\my path\my task.log" 2>&1"
上面的例子演示了这些特性:
路径/文件名中允许有空格。如果路径中没有空格,那么可以去掉嵌套引号:/c "C:\path\task.cmd >> C:\path\task.log 2>&1"
附加到日志。如果你想每次都覆盖日志,那么使用>
而不是>>
在日志中同时包含 STDOUT 和 STDERR。如果您只想要 STDOUT,则删除 2>&1
【讨论】:
以上是关于如果脚本正在由任务调度程序运行,我如何捕获它的输出?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Messagebox 在 Windows 7 任务调度程序中启动 VBS 脚本?
从 Windows 任务调度程序在虚拟环境中运行 python 脚本