【问题标题】:Get-Content -Wait is locking the file while it reads it, preventing Add-Content from writing dataGet-Content -Wait 在读取文件时锁定文件,防止 Add-Content 写入数据
【发布时间】:2015-06-09 13:35:19
【问题描述】:

我正在使用 powershell 来写入和读取日志文件。

一个脚本正在使用 Add-Content 生成一个日志文件。另一个脚本正在跟踪日志文件,使用 Get-Content -Wait。这似乎应该是相当可靠的。

但是,作者经常写不出来,读者也经常看不懂而放弃。我只能假设这两个命令没有使用适当的访问标志打开文件,因此它们相互争斗。

这是一个令人讨厌的小脚本,它演示了同一进程中的两个作业的问题,尽管在不同的 powershell 进程之间也会发生同样的情况:

$writer = start-job -ScriptBlock {     
    foreach($i in 1..500)
    {
        "$i" | Add-Content "c:\temp\blah.txt"
        Sleep -Milliseconds 10
    }
}

$reader = start-job -ScriptBlock { 
    Get-Content "c:\temp\blah.txt" -wait
}

while($writer.State -eq "Running")
{
    Sleep 1
}
Sleep 2

"Checking writer"
receive-job $writer

"Checking reader"
receive-job $reader

remove-job $writer -force
remove-job $reader -force

在装有 powershell 3 ISE 的 Windows 7 x64 机器上,我通常会遇到很多写入错误:

Checking writer
The process cannot access the file 'C:\temp\blah.txt' because it is being used by another process.
    + CategoryInfo          : ReadError: (C:\temp\blah.txt:String) [Get-Content], IOException
    + FullyQualifiedErrorId : GetContentReaderIOError,Microsoft.PowerShell.Commands.GetContentCommand
    + PSComputerName        : localhost

然后正在读取的文件中有间隙:

Checking reader
...
23
24
25
54
55
56
...

注意,这与此处讨论的问题不同:Get-Content -wait not working as described in the documentation 和此处:https://social.technet.microsoft.com/Forums/windowsserver/en-US/e8ed4036-d822-43d3-9ee5-dd03df3d9bfc/why-doesnt-wait-work-and-why-doesnt-anyone-seem-to-care?forum=winserverpowershell 是关于在写入之间跟踪未关闭的文件。

有没有办法像这样使用 Get-Content 和 Add-Content,还是我应该放弃,用别的东西来读写我的日志文件?

【问题讨论】:

    标签: powershell powershell-3.0


    【解决方案1】:

    尝试使用 Out-File 而不是 Add-Content

    替换

    Add-Content "c:\temp\blah.txt"
    

    与:

    Out-File "c:\temp\blah.txt" -Append -Encoding ascii
    

    如果这是您想要的,您需要使用 Out-File 将编码指定为 ascii,因为它是 add-content 的默认值,但不是 out-file 的默认值。您还需要使用 -append 和/或 -noclobber 来避免覆盖现有文件内容。

    【讨论】:

    • 一种解决方法是复制文件并读取它,我怀疑它可能是它的速度,所以你也可以开始睡眠
    • @Nick 复制文件也会遇到同样的问题 - 它可能与 Add-Content 冲突,导致写入失败。这种方法也没有 -Wait 语义,这是使用 Get-Content 的原因。参考文献bash 中的尾巴。休眠不是解决方案,它们只是降低了出现问题的可能性,使其在测试中更难被发现,但在生产中同样具有破坏性。
    • @campbell Out-File 可以解决问题。这似乎是 Add-Content 中的一个错误(或至少是一个缺失的功能),是粗心的脚本编写者陷入的陷阱。添加内容是否有害?
    • 这是 Add-Content 中的一个错误,已修复,但在 PowerShell 5.1 中未修复。 github.com/PowerShell/PowerShell/issues/5924
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-13
    • 1970-01-01
    • 1970-01-01
    • 2019-10-01
    • 2014-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多