I want to tail a file and call a function when a new line is added. This is what I'm trying but it's not printing anything out which makes me think that the Get-Content
isn't working.
function Check-LogLine {
param (
$Line
)
...
}
$Global:Line = Get-Content -Path $LogPath -Tail 1 -Wait
Write-Output "Line: $Global:Line"
while ($Line -NotLike "*Stopping!") {
$Global:Line = Get-Content -Path $LogPath -Tail 1 -Wait
Write-Output $Global:Line
Check-LogLine -Line $Global:Line
}
-= Edit =-
It gets the last line if I remove the -Wait
but it keeps getting the same last line over and over.
CodePudding user response:
You're never getting into the while
loop, -Wait
is blocking the thread on the first call:
$Global:Line = Get-Content -Path $LogPath -Tail 1 -Wait
You can use the pipeline instead which is meant for this, I will go and assume since you're using -Wait
this will be a somewhat interactive process and you only want output to the console doesn't matter if the output goes to the Success Stream or the Information Stream. If that's the case, you can use Select-Object -First 1
to properly break the pipeline. Otherwise, if you really need the output to go the Success Stream, the solution would be very cumbersome.
Here is an example of how you can approach your code:
function Check-LogLine {
param($Line)
# Writing to the Information Stream
# (this output is not passed thru the pipeline)
Write-Host "[$([datetime]::Now.ToString('u'))] $line"
}
$tmp = New-TemporaryFile
# This job will run in the background writing to a temp file each 2 seconds
$job = Start-Job {
$tmp = $using:tmp
0..10 | ForEach-Object {
Start-Sleep 2
if($_ -ne 5) {
"$_ ... Running!" | Add-Content $tmp.FullName
return
}
"$_ ... Stopping!" | Add-Content $tmp.FullName
}
}
try {
Get-Content $tmp.FullName -Wait -Tail 1 | ForEach-Object {
# The output to this function goes to the Info Stream
Check-LogLine $_
if($_ -like '*Stopping*') {
Write-Host 'Stopping here...'
$job | Stop-Job | Remove-Job
'this output goes to Success Stream to stop this pipeline...'
}
} | Select-Object -First 1
}
finally {
$tmp | Remove-Item
}