为何在PowerShell的ForEach-Object循环中使用continue会报错?
PowerShell外部命令管道结合ForEach-Object使用continue报错问题解析
问题现象
当直接把外部命令(比如ipconfig、nslookup)的输出通过管道传给ForEach-Object循环时,在循环脚本块里用continue语句会触发NativeCommandFailed错误。
正常运行的代码
ipconfig | ForEach-Object { $_ }
触发报错的代码
ipconfig | ForEach-Object { $_ continue }
报错信息
Program 'ipconfig.exe' failed to run: System error.At C:\Users\test\ps.ps1:1 char:1 + nslookup google.com | ForEach-Object { + ~~~~~~~~~~~~~~~~~~~. At C:\Users\test\ps.ps1:1 char:1 + nslookup google.com | ForEach-Object { + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ResourceUnavailable: (:) [], ApplicationFailedException + FullyQualifiedErrorId : NativeCommandFailed
这个问题对所有外部命令都适用,循环内处理的对象都是字符串;但如果先把外部命令的输出保存到变量,再通过管道传给ForEach-Object循环,就能正常执行。
原因分析
PowerShell在处理外部命令的管道流时,若用continue中断当前迭代,会提前关闭和外部命令之间的管道连接。外部命令此时还在输出内容,突然发现管道被关闭,就会报错退出,进而触发NativeCommandFailed异常。
如果先把输出存入变量,外部命令已经完整执行并把所有输出写入内存,后续的管道操作是基于内存里的数据进行,不会影响外部命令的运行状态,自然不会报错。
解决方案
方案1:先缓存外部命令输出到变量
$output = ipconfig $output | ForEach-Object { $_ continue }
方案2:用return替代continue
在ForEach-Object的脚本块中,return只会结束当前迭代,不会关闭外部命令的管道连接,因此不会触发报错:
ipconfig | ForEach-Object { $_ return }
内容的提问来源于stack exchange,提问作者DeadChex
相关产品推荐
相关产品推荐

