Перезаписать файл, если новый сеанс, но добавить, если тот же сеанс - PullRequest
2 голосов
/ 28 мая 2019

У меня есть функция для преобразования любых write-hosts в скрипте (оставляя их для целей раскраски позже) в tee object

function Write-Host($object) 
{
    $object | tee .\LOG.txt -Append
}

В настоящее время он добавляется в файл, если он существует (или создает его, если его нет)

Я хочу создать его каждый раз, когда начинается новый сеанс. добавлять в файл только в том случае, если вы находитесь в том же сеансе

как мне это сделать?

Ответы [ 3 ]

1 голос
/ 29 мая 2019

Вы не определяете, что для вас означает новый "сеанс", поэтому давайте использовать переменную $PID, которая является идентификатором процесса, под которым работает PowerShell.

В идеале вы просто должны сделатьэта часть имени файла, так что каждый процесс имеет свой собственный журнал.Но вы заявили в комментариях, что вы не хотите нескольких файлов.В этом случае запишите PID в качестве первой строки в файле и читайте его каждый раз.

function Write-Host($object) 
{
    $filename = '.\LOG.txt'

    $logPID = Get-Content -LiteralPath $filename -ReadCount 1 -ErrorAction Ignore
    $newSession = $logPID -ne $PID

    if ($newSession) {
        $PID | Set-Content -LiteralPath $filename
    }

    $object | Tee-Object -FilePath $filename -Append
}
1 голос
/ 29 мая 2019

Я предложу альтернативный метод для будущих поисковиков.Вы можете получить время начала текущего процесса, сравнить его с моментом создания файла и удалить файл, если он был создан до запуска текущего идентификатора PID.

function Write-Host
{
[cmdletbinding()]
Param([parameter(ValueFromPipeline=$true)]$object)
Begin{
    $allObjects=New-Object System.Collections.ArrayList
}
Process{
    $allObjects.Add($object)|out-null
}
End{
    if((test-path .\log.txt) -and (get-item '.\LOG.txt').CreationTime -lt (Get-Process -Id $PID).StartTime){Remove-Item .\LOG.txt}
    $allObjects | tee .\LOG.txt -Append
}
}

Plus с преобразованием врасширенная функция, которую вы можете просто передать в нее, например:

Get-Process | Write-Host

Или я полагаю, что самое простое, что нужно сделать, это просто удалить файл журнала, как первое, что делает ваш скрипт.

1 голос
/ 29 мая 2019

Это один из немногих случаев, когда глобальные переменные полезны, потому что они могут сохраняться в течение всего сеанса. В этом примере я использую их, чтобы установить уникальное имя файла (в данном случае сегодняшнюю дату), чтобы войти в систему:

function Write-Host($object) 
{
    if($global:LogFile -eq $null)
    {
        $global:LogFile = ".\LOG-$(Get-Date -Format 'yyyy-MM-dd').txt"
    }

    $object | tee $global:LogFile -Append
}

--- Редактировать: ---

Из комментариев, если вы хотите иметь новый файл в начале сеанса и добавлять его во время сеанса, мы все равно можем использовать глобальную переменную для определения начала сеанса, но мы просто используем проверку, чтобы удалить файл в начале, и оставить приложение к тройнику:

function Write-Host($object) 
{
    if($global:LogFile -eq $null)
    {
        $global:LogFile = ".\LOG.txt"
        Remove-Item $global:LogFile -ErrorAction SilentlyContinue
    }

    $object | tee $global:LogFile -Append
}

--- Редактировать 2: ---

Со второго комментария:

Remove-Item - другое животное, потому что по умолчанию оно не выводится. Действительно, единственный способ получить любой вывод - это добавить параметр -Verbose. Но Tee-Object не захватывает подробный поток. Чтобы обойти это, мы должны использовать два трюка. Сначала мы указываем параметр -Verbose (чтобы получить вывод) с перенаправлением ( about_Redirection ), чтобы перенаправить подробный поток (4) в стандартный поток Success (1) / Information. Это позволит Tee-Object собирать информацию из командлета Remove-Item:

Remove-Item test.txt -Verbose 4>&1 | Tee-Object out.txt
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...