2

我正在编写一个在 Linux 上运行的 powershell 脚本。此脚本的目的是运行 MS SQL Server 并显示其输出,但是当用户按下Ctrl+C或发生某些错误时,脚本会获取数据文件夹的副本,然后退出。

[CmdletBinding()]
PARAM (
    [Parameter(ValueFromPipelineByPropertyName)]
    [string] $Command,

    [Parameter(ValueFromPipelineByPropertyName)]
    [string] $Args
)
BEGIN {
    Write-Output "started $PSScriptRoot"
    $currentErrorLevel = $ErrorActionPreference
    # [console]::TreatControlCAsInput = $true
}
PROCESS {

    try {
        $ErrorActionPreference = 'SilentlyContinue';
        $IsSqlRunning = Get-Process -name "sqlservr";

        if ($null -eq $IsSqlRunning) {
            start-process "/opt/mssql/bin/sqlservr" -wait -NoNewWindow
        }
    }
    catch {
        $ErrorActionPreference = $currentErrorLevel;
        Write-Error $_.Exception
    }

}
End {
    $ErrorActionPreference = $currentErrorLevel;
    #do backup
    Create-Backup "/opt/mssql/bin/data"
    Write-Output "finishd!"
}

这个脚本有几个问题:

  • 当我按Ctrl+C时,它会破坏主脚本,并且它永远不会到达Create-Backup脚本底部的部分。
  • 如果我删除-Wait,那么脚本将不会显示 sql 日志输出

所以我首选的解决方案是使用-Wait参数运行 sql 并阻止 powershell 在我按Ctrl+后退出代码C,而是Ctrl+C关闭 sql 实例

所以我正在寻找一种方法来实现两者。

4

1 回答 1

1

为简单起见,我假设您的函数只需要支持单个输入对象,因此我使用一个没有begin,processend块的简单函数体,这相当于只有一个end块:

[CmdletBinding()]
PARAM (
    [Parameter(ValueFromPipelineByPropertyName)]
    [string] $Command,

    [Parameter(ValueFromPipelineByPropertyName)]
    [string] $Args
)
    Write-Output "started $PSScriptRoot"

    # No need to save the current value, because the modified
    # value is local to the function and goes out of scope on 
    # exiting the function.
    $ErrorActionPreference = 'SilentlyContinue';

    try {
        $IsSqlRunning = Get-Process -name "sqlservr";

        if ($null -eq $IsSqlRunning) {
            start-process "/opt/mssql/bin/sqlservr" -wait -NoNewWindow
        }
    }
    catch {
        Write-Error $_.Exception
    }
    finally {

      # This block is *always* called - even if Ctrl-C was used.

      Create-Backup "/opt/mssql/bin/data"
      # CAVEAT: If Ctrl-C was used to terminate the run, 
      #         you can no longer produce *pipeline* input at this point
      #         (it will be quietly ignored).
      #         However, you can still output to the *host*.
      Write-Host "finished!"

    }

如果你真的需要支持多个输入对象,它会变得更加复杂。

于 2020-05-14T12:03:10.627 回答