我正在使用Puppet的Exec Powershell提供程序来运行一些PowerShell脚本。 我遇到了执行脚本的问题。 执行的方法导致脚本运行结束。 我被迫自己杀死这个进程,但脚本本身似乎正常运行。
我已经能够举出一个简单的例子,并缩小原因。
重现步骤
我很确定这个问题与我正在执行SQLCMD.exe的方式有关,或者与执行需要多长时间有关(大约一秒)
$instance = ''; $latest_output = "Hi"; $cmd = "sqlcmd.exe -E -S .$instance -h -1 -m 1 -Q `"SET NOCOUNT ON; USE [master]; SELECT @@VERSION;`""; $output = [string](cmd.exe /C "$cmd"); $output = $output.Trim(' '); if ($output -eq $latest_output) { Write-Host "Up to date."; } else { Write-Host "Updating..."; }
打开CMD.exe,运行以下命令,该命令按预期工作:
C:\Users\Administrator>powershell.exe -Command C:\backups\scripts\test.ps1 Updating... C:\Users\Administrator>
现在执行这样的脚本,这个脚本无限地执行。 这是Puppet中的Exec提供程序使用的有问题的语法:
C:\Users\Administrator>powershell.exe -Command - < C:\backups\scripts\test.ps1 Updating... Updating... Updating... Updating...
如果我joinexit; 到test.ps1的结尾,它只执行一次。
我原来的问题是,我怎么能避免这个? 但增加exit这个对我来说。 剩下的唯一问题是: 为什么会发生这种情况?
编辑 :只要你带来一个语法错误/exception到脚本(例如。缺less逗号)脚本将无限执行,每次抛出exception。 所以虽然exit是一种解决方法,但它仍然是危险的,因为它不适用于例外。
Powershell似乎对它作为标准input收到的内容很敏感(使用<redirectstdin)。 它可能正在接收不期望的字符。 我会build议删除所有换行符,并保存在记事本中的脚本。 所以你的脚本看起来像这样:
$instance = ''; $latest_output = "Hi"; $cmd = "etc...
通过less数testing,我根据所使用的编码,空格和字符收到了不同的行为。 可能只是cmdredirectinput的方式。
您也可能希望将您的问题发布到github中的powershell puppet项目 。
此外,你可能不想使用写主机,因为它是一个标准输出到控制台,也可能是问题。
在一个稍微不相关的笔记试试这个:
$psi = New-Object System.Diagnostics.ProcessStartInfo; $psi.FileName = "powershell.exe" $psi.UseShellExecute = $false $psi.RedirectStandardInput = $true $p = [System.Diagnostics.Process]::Start($psi)
按ctrl-c,那么你应该看到这样的事情:
PS C:\> PS C:\>
当涉及到inputredirect时,Powershell显然会performance出更奇怪的行为。