【问题标题】:Batch closes prematurely on a for /f command批处理在 for /f 命令上过早关闭
【发布时间】:2010-09-20 15:36:57
【问题描述】:

我有一个批处理文件(在 Windows XP 中,已激活命令扩展名),其中包含以下行:

for /f %%s in ('type version.txt') do set VERSION=%%s

在某些计算机上,它可以正常工作(如 this SO question 所示),但在其他计算机上它会杀死 cmd(控制台窗口刚刚关闭)

为什么?


注意:计算机似乎具有类似的配置:XpSP2,用户具有管理权限,在 HKEY_CURRENT_USER\Software\Microsoft\Command Processor 中没有定义“命令处理器”...

【问题讨论】:

  • 感谢您的编辑,Oli:我想将那个问题标记为“脚本”,但 SO 标记上的自动完成功能欺骗了我 ;)

标签: batch-file


【解决方案1】:

我得到了第一个经验性答案:

for /f %%s in (version.txt) do ...

在每台计算机上都可以正常工作。

似乎for /f 与文件名一起使用,而不是与“类型文件名”之类的任何 dos 命令一起使用。

但是,并非所有客户的计算机都如此(在某些情况下,“类型文件名”工作正常)

如果您想要 15(简单?)点 ;-),您可以回答以下问题:
为什么 'for /f' 有时不能用于文件名以外的任何内容。为什么它只是关闭 DOS 会话?


编辑:3 年后(!),barlop 遇到了类似的情况,在问题“for /f closes cmd prompt immediately?”中有详细说明。他的结论是:

COMSPEC 确实在执行 SET+ENTER 时被列出。
所以,我打开环境变量窗口,看到COMSPEC 没有在用户或系统变量下列出。我将它添加到系统变量中,启动了命令提示符,它似乎工作正常。

Andriy M 在回答 barlop 的问题时提到的 thread on ss64 forum 包含详细信息。

for”循环中的脱壳以完成“dir”(或您要求完成的任何命令)需要设置 ComSpec 以重新加载 cmd 窗口。

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\ComSpec=
%SystemRoot%\system32\cmd.exe

【讨论】:

  • 也许提供15分不切芥末? :-) 老实说,我未能重现您提到的行为。你能发布更多细节吗?
  • 感谢 Tomalak 抽出时间检查该问题。问题是,除了已经提到的那个之外,我没有太多细节:在一个客户的 PC 上,在 DOS 会话中,我键入“for /f %s in ('type afilename.txt') do echo %s”,然后。 ..“噗”不再有 DOS 窗口...
  • 我会继续这样做,但我想与 SO 社区确认以前是否已经看到过这个问题。显然不是。我会发布我可能找到的任何结论。
  • 我没有来自我们自己的支持团队的任何准确答案,所以我现在“接受”我自己的答案(没有任何声誉提升)
  • @VonC 为什么你接受自己的答案,但它没有回答?
【解决方案2】:

关于命令扩展,有可能使用 /E:OFF 调用 CMD.EXE,从而禁用命令扩展(即使在注册表中启用)。

如果在脚本中使用命令扩展 shell 选项,强烈建议您在脚本开头执行以下技巧。

-- 粘贴自http://www.ss64.com/nt/setlocal.html的信息

如果给定一个参数,SETLOCAL 将设置一个 ERRORLEVEL。如果给出了两个有效参数之一,则它将为零,否则为零。

您可以在批处理文件中使用它来确定命令扩展是否可用,使用以下技术:

VERIFY errors 2>nul
SETLOCAL ENABLEEXTENSIONS
IF ERRORLEVEL 1 echo Unable to enable extensions

这是因为“验证错误”将 ERRORLEVEL 设置为 1,然后如果扩展不可用(例如,如果脚本在 command.com 下运行),SETLOCAL 将无法重置 ERRORLEVEL 值

如果命令扩展被永久禁用,则 SETLOCAL ENABLEEXTENSIONS 将不会恢复它们。

【讨论】:

  • 感谢您的详细回答...仍然没有运气。即使 ENABLEEXTENSIONS 已成功激活,DOS 窗口仍会自行关闭...
【解决方案3】:

等等……难道你的文件名周围有撇号吗? MS 是说文件名集有双引号,而文字字符串有撇号。

for /F ["usebackqParsingKeywords"] {%% | %}variable in ("filenameset") do command [CommandLineOptions]

for /F ["usebackqParsingKeywords"] {%% | %}variable in ('LiteralString') do command [CommandLineOptions]

for /F ["usebackqParsingKeywords"] {%% | %}variable in (`command`) do command [CommandLineOptions]

当然,除非你这样做。

您可以使用 for /F 解析逻辑 在直接字符串上,通过包装 之间的文件名集 单引号中的括号 (即“文件名集”)。文件名集 被视为单行输入 从文件中提取,然后对其进行解析。

【讨论】:

  • 感谢Keng 的建议。我明天上班去看看。
  • 啊...不:最后一个表单 (command) 将立即关闭 DOS 窗口
【解决方案4】:

如果命令扩展被禁用,for 命令的 (set) 参数必须是一个文件。

如果启用了命令扩展,则 for 命令的 (set) 参数可以是文件、字符串或命令。

在“类型文件名”设置失败的客户端计算机上禁用命令扩展。

有关启用或禁用命令扩展的信息,请键入“cmd /?”

【讨论】:

  • 他提到命令扩展被激活(我猜是一致的)。
  • 是的,但根据 Craig 的说法,我会再次检查。可以肯定的是,克雷格,您能否详细说明验证命令扩展是否启用的标准?
  • 该死...我刚刚检查并重新检查了注册表,确实启用了命令扩展,并且没有其他特殊值突出。 windows 事件不会显示任何异常。 cmd /E:ON 仍然在 for /f in ('command') 命令行中自行关闭...令人沮丧 ;)
  • 如果我没记错的话,有可能 CMD.EXE 是用 /E:OFF 调用的,因此命令扩展被禁用。我建议你在 DOS shell 中运行这些:VERIFY errors 2>nul SETLOCAL ENABLEEXTENSIONS IF ERRORLEVEL 1 echo Unable to enable extensions
【解决方案5】:

是不是文件没有扩展名,所以cmd把它当成一个不存在的目录?

【讨论】:

  • 实际上,该文件确实存在并且具有扩展名(文件名只是一个 foobar 名称):“for /f %s in ('type afilename.txt') do echo %s” 触发立即关闭 DOS 窗口
猜你喜欢
  • 1970-01-01
  • 2011-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多