如何抑制输出并检查命令是否成功?

How to suppress output and check whether or not a command is successful?

我正在尝试编写一个 powershell 脚本,通过使用 $? 检查是否发生错误来测试 MySQL 登录是否成功。

我还想禁止命令的所有输出(成功或不成功)。

这些是我尝试过的东西:

mysql -u root --password=mypass -e "show databases"
If ( $? ) {
  echo "Hooray!"
} Else {
  echo "Boo!"
}

这可以正常工作,但不会抑制任何输出。

mysql -u root --password=mypass -e "show databases" > $null

仍然可以正常工作,但如果密码错误,则不会抑制错误。

mysql -u root --password=mypass -e "show databases" 2> $null

这不能正常工作。在这个例子中,它总是打印 "Boo!"

mysql -u root --password=mypass -e "show databases" > $null 2>&1

这会正确抑制所有输出,但只会像以前一样打印 "Boo!"。

更新:

  • if ($LASTEXITCODE -eq 0) ... 方法将继续与外部程序一起稳健地工作。
  • 但是,在 PowerShell(核心)7.2 及更高版本 中,if ($?) ... 也能正常工作 - 请参阅 获取更多信息。

使用 $LASTEXITCODE -eq 0 而不是 $? 来可靠地检测外部程序报告的非零退出代码(通常是信号失败)。

然后您可以使用*> $null明确抑制所有输出,而不必担心重定向对$?的影响:

mysql -u root --password=mypass -e "show databases" *>$null
if ($LASTEXITCODE -eq 0) {
  "Hooray!"
} else {
  "Boo!"
}

使用涉及 PowerShell 错误流的 重定向 - 通过 2> 显式或通过 *> 隐式 - 意味着如果通过该错误流接收到任何数据stream - 在调用外部程序的情况下,这意味着 来自 stderr 的任何输出 - PowerShell 将 $? 设置为$false.

然而,在外部控制台/终端程序领域,stderr 不仅用于输出 error 信息,还包括任何不是 的信息data,比如状态信息。因此,您不能从 stderr 输出的存在推断故障

外部控制台/终端程序仅通过其 退出代码 传达其成功状态,PowerShell 反映在自动 $LASTEXITCODE 变量中。

从上面可以看出,即使退出代码是 0$? 也可以是 $false,因此它不是一个可靠的成功指标 -不像 $LASTEXITCODE.