我正在使用 Puppet 的 Exec Powershell 提供程序来运行一些 powershell 脚本。我对它执行我的脚本的方式有疑问。执行方法导致脚本反复运行。我被迫自己杀死进程,但脚本本身似乎运行正常。
我已经能够整理一个简单的例子,并缩小原因。
重现步骤
- 使用以下内容创建C:\backups\scripts\test.ps1:
我很确定这个问题与我执行 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...
如果我添加
exit;
到 test.ps1 的末尾,它只会执行一次。
我最初的问题是,我怎样才能避免这种情况?但是添加exit
对我来说是这样的。剩下的唯一问题是:为什么会发生这种情况?
编辑:一旦您将语法错误/异常带入脚本(例如缺少逗号),脚本将无限执行,每次都抛出异常。因此,虽然exit
是一种解决方法,但它仍然很危险,因为它不适用于异常。
环境
- Windows 2008 R2 服务器标准版
- 具有高级服务的 Microsoft SQL Server Express 10.50.2500
- 电源外壳 2.0
Powershell 似乎对它作为标准输入接收的内容很敏感(使用 < 来重定向标准输入)。它可能正在接收它不期望的字符。我建议删除所有换行符并将脚本保存在记事本中。所以你的脚本看起来像这样:
通过我所做的少数测试,我收到了根据所使用的编码、空格和字符不同的行为。可能只是cmd 重定向输入的方式。
您可能还希望将您的问题发布到 github 中的powershell puppet 项目。
此外,您可能不想使用 write-host,因为它是控制台的标准输出,也可能是问题。
在稍微不相关的注释上试试这个:
点击 ctrl-c 然后你应该看到如下内容:
当涉及到输入重定向时,Powershell 肯定会表现出奇怪的行为。