【问题标题】:How to catch terminating error and still continue my PowerShell script如何捕获终止错误并仍然继续我的 PowerShell 脚本
【发布时间】:2018-02-21 23:28:37
【问题描述】:

我需要您的帮助来改进我的脚本并正确处理异常。 我有一个脚本来删除 .log 文件中的行,使用日期比较来定义它是否足够旧,如果为真,则删除行。 这是我需要帮助的脚本部分:

Foreach ($Fichier in $Fichiers)
{
    try
    {
        (Get-Content $Fichier) |
            Where-Object {$_} |
            Where-Object { ([datetime]::ParseExact(([string]$_).Substring(0,19), $Format, $Culture) -ge (Get-Date).AddDays(-$Jours)) } |
            Set-Content $Fichier
        LogMessage -Message "Fichier $Fichier purgé des toutes les lignes datant de plus de $Jours jours"
    }
    catch
    {
        $ErrorMessage = $_.Exception.Message
        $FailedItem = $_.Exception.ItemName
        LogMessage -Message "$FailedItem - $ErrorMessage"
    }
}

问题是我的 .log 有这样的行

[ 30-10-2017 16:38:11.07 | INFO    | XXX.ActiveMQ.ConsumerService.Business.TransactionConsumerTopic | WriteMessageToDlq    ] - Le traitement du message ID:XXXXX-56720-1509361559247-13:1:1:1:1 a rencontré une erreur côté Web Service : TKO / JMS_3.9.47612_2017-10-30 16:38:00.937_TKO / 3.9.47612 / 2017-10-30 16:38:00.937 / 
[1];Erreur non-gérée : Une erreur applicative est survenue.

如您所见,第一行对我的脚本来说是可以的,它进行子字符串和日期比较,但有时在文件中,第二行不正常,因为它引发错误,终止错误因为我的脚本无法继续

Exception lors de l'appel de « ParseExact » avec « 3 » argument(s) : « La chaîne n'a pas été reconnue en tant que DateTime valide. »

如果日期比较出现错误,我会尝试找到一种方法转到下一行。 在@Luka-Klarić 发表评论后,我也尝试过这种方式

try
    {
        (Get-Content $Fichier) |
            Where-Object {$_} |
            Where-Object { ([datetime]::ParseExact(([string]$_).Substring(0,19), $Format, $Culture) -ge (Get-Date).AddDays(-$Jours)) } -ErrorAction SilentlyContinue |
            Set-Content $Fichier
        LogMessage -Message "Fichier $Fichier purgé des toutes les lignes datant de plus de $Jours jours"
    }
    catch
    {
        $ErrorMessage = $_.Exception.Message
        $FailedItem = $_.Exception.ItemName
        LogMessage -Message "$FailedItem - $ErrorMessage"
        Continue
    }

但它也不起作用。对于像我这样的 PowerShell 菜鸟,我们非常感谢您提供任何帮助,并询问您是否需要更多信息。

编辑:我已经改变了解决该问题的方法,并以这种方式找到了解决方案 -> Purge with PowerShell a big log file by deleting line by line and stopping it when my date comparison is true

【问题讨论】:

标签: powershell parsing datetime exception


【解决方案1】:

所以如果我的理解是正确的,你想知道为什么LogMessage -Message "Fichier $Fichier purgé des toutes les lignes datant de plus de $Jours jours"在遇到终止错误时无法运行?

如果是这种情况,那是因为try{}catch{} 立即移动到捕获处,然后立即越过该块继续前进。

如果您需要即使在出现错误的情况下也能运行该行,请将其放在 catch 块中,或者查看将从下一行代码恢复的 trap{},这与try{}catch{}

编辑:

try
{
    write-host "line 1" -ForegroundColor Magenta
    throw "custom"
    write-host "line 2" -ForegroundColor Magenta
}
catch
{
    write-host "womp womp" -ForegroundColor Red
}

对比:

trap
{
    write-host "womp womp" -ForegroundColor Red
}    

write-host "line 1" -ForegroundColor Magenta
throw "custom"
write-host "line 2" -ForegroundColor Magenta

这些示例可能会有所帮助,除非它比我理解的更复杂。

【讨论】:

  • 谢谢,但我真的不需要在我的脚本中执行该行,但如果该行没有日期,我需要转到我打开的文件中的下一行。但也许我需要以不同的方式思考它,因为该日志文件比我想象的要复杂一些。并非所有的行都有日期,所以也许我做一个子字符串然后转换为日期的方式不是正确的。
  • 哦,你能读入整个文件,通过 RegEx 只保留与你的模式匹配的行,然后将其发送到你的循环中吗?
  • 我已经改变了解决该问题的方法,并通过这种方式找到了解决方案 -> 使用 PowerShell 清除大日志文件,方法是逐行删除并在我的日期比较为真时停止它
【解决方案2】:

通常try{}catch{} 避免你的程序停止:

$dates = "05/12/2012", "5/12/2012", "05/12/2012"
foreach($date in $dates){try{[datetime]::ParseExact($date, "dd/mm/yyyy", $null )}catch{}}

第二个日期产生异常但脚本仍在继续。

【讨论】:

  • 我试图把它放在我的 Where-Object 子句中,但没有按预期工作。
  • 您可以编辑您的问题以提供修改后的代码吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-04-24
  • 1970-01-01
  • 2017-03-07
  • 1970-01-01
  • 2011-10-20
  • 1970-01-01
  • 2019-10-02
相关资源
最近更新 更多