programing

Get-Content - 문서에 설명된 대로 작동하지 않을 때까지 기다립니다.

megabox 2023. 10. 1. 19:22
반응형

Get-Content - 문서에 설명된 대로 작동하지 않을 때까지 기다립니다.

Get-Content path/to/logfile -Wait은 실제로 .한 후 고치면 sGet-Content로그 파일의 최신 변경 내용을 출력합니다.

해보면.tail -fcygwin하여를에 사용하지 음)get-content 그런 제가 도 할 합니다.) .

왜 이런 일이 일어나는지 아는 사람?

편집: Bernhard König는 이것이 마침내 파워셸 5에서 해결되었다고 논평에서 보고합니다.

당신 말이 맞아요. 그.-Wait:nGet-Content파일이 닫힐 때까지 기다렸다가 더 많은 내용을 읽습니다.파워셸에서 이를 시연하는 것은 가능하지만, 다음과 같은 루프와 같이 바로 잡기가 어려울 수 있습니다.

while (1){
get-date | add-content c:\tesetfiles\test1.txt 
Start-Sleep -Milliseconds 500
}

는 루프를 돌 때마다 출력 파일을 여닫습니다.

이 문제를 설명하려면 두 개의 Powershell 창(또는 ISE의 두 탭)을 엽니다.한 번에 다음 명령을 입력합니다.

PS C:\> 1..30 | % { "${_}: Write $(Get-Date -Format "hh:mm:ss")"; start-sleep 1 } >C:\temp\t.txt

파일에 1초에 한 줄씩 적으면 30초 동안 실행되지만 매번 파일을 닫고 열지는 않습니다.

에서는 다음을 합니다.Get-Content파일 읽기:

get-content c:\temp\t.txt -tail 1 -wait | % { "$_ read at $(Get-Date -Format "hh:mm:ss")" }

-Wait명령을 중지하려면 C+를 사용해야 합니다. 명령을 실행하면 처음 2개에서 몇 초 후에 3번 대기하고 세 번째에서 다음 출력을 제공한 후에 더 오래 기다리십시오.

PS C:\> get-content c:\temp\t.txt -tail 1 -wait | % { "$_ read at $(Get-Date -Format "hh:mm:ss")" }
8: Write 12:15:09 read at 12:15:09

PS C:\> get-content c:\temp\t.txt -tail 1 -wait | % { "$_ read at $(Get-Date -Format "hh:mm:ss")" }
13: Write 12:15:14 read at 12:15:15

PS C:\> get-content c:\temp\t.txt -tail 1 -wait | % { "$_ read at $(Get-Date -Format "hh:mm:ss")" }
19: Write 12:15:20 read at 12:15:20
20: Write 12:15:21 read at 12:15:32
21: Write 12:15:22 read at 12:15:32
22: Write 12:15:23 read at 12:15:32
23: Write 12:15:24 read at 12:15:32
24: Write 12:15:25 read at 12:15:32
25: Write 12:15:26 read at 12:15:32
26: Write 12:15:27 read at 12:15:32
27: Write 12:15:28 read at 12:15:32
28: Write 12:15:29 read at 12:15:32
29: Write 12:15:30 read at 12:15:32
30: Write 12:15:31 read at 12:15:32

이를 통해 분명히 알 수 있습니다.

  1. 명령을 실행할 때마다 파일에 최신 행이 기록됩니다.캐싱에도 문제가 없고 플러시가 필요한 버퍼도 없습니다.
  2. 한 줄만 읽은 다음 다른 창에서 실행 중인 명령이 완료될 때까지 추가 출력이 나타나지 않습니다.
  3. 완료되면 보류 중인 모든 행이 함께 나타납니다.소스 프로그램이 파일을 닫으면서 이 문제가 발생한 것으로 보입니다.

도.Get-Content두 개의 다른 창에서 실행되는 명령어는 하나의 창에서 줄 3을 읽고 그냥 기다렸고, 다른 창에서는 줄 6을 읽어서 줄이 확실히 파일에 쓰여지고 있습니다.

는 꽤 인 것 .-Wait은 파일 의 옵션이지,된 1다를 기다리는 중이 .설명서가 틀렸습니다.

편집: Adi Inbar가 제가 틀렸다고 주장하는 것 같기 때문에 여기서 예를 든 사람들은 파워셸 토론에 가장 적합해 보이는 파워셸만 사용해야 한다고 덧붙여야 합니다.또한 Python을 사용하여 동작이 설명한 것과 정확히 일치하는지 확인했습니다.

쓴은 새로운 로 수 .Get-Content -Wait응용 프로그램이 버퍼를 플러시한 경우 명령을 즉시 실행합니다.

(instance)를 Get-Content -Wait나중에 시작된 다른 Powershell 인스턴스가 나중에 데이터를 보더라도, 는 작성 중인 파일에 새 내용을 표시하지 않습니다.합니다가 할 수 으로 증명합니다.Get-Content -Wait는 1초 간격으로 폴링하지 않고 다음에 데이터를 찾기 전에 트리거 이벤트를 기다립니다.

한 파일 dir는 라인이 추가되는 동안 업데이트되고 있으므로 디렉토리 엔트리 크기가 업데이트되기를 기다리는 경우는 아닙니다.

,Get-Content -Wait새 컨텐츠를 거의 즉시 표시합니다.데이터를 디스크에 플러시할 때까지 대기하는 경우 Windows에서 디스크 캐시를 플러시할 때까지 최대 지연됩니다.

@AdiInbar, 파일을 저장할 때 Excel이 하는 작업을 이해하지 못하실 것 같습니다.자세히 보세요.ftest.xlsx다도 .~test.xlsx동일한 폴더에 저장합니다. 사용합니다.dir ~test.xlsx -hidden | select CreationTime그것이 언제 만들어졌는지 확인해요파일 저장 후 지금test.xlsx입니다에서 을 가질 입니다.~test.xlsx, 하면 . , Excel 됩니다에 됩니다.~을 바꿉니다.~새다를 .~파일이요. 거기에는 많은 개폐가 이루어지고 있습니다.

저장하기 전에는 열려 있는 파일이 있고, 해당 파일이 열린 후에는 열려 있지만 다른 파일입니다.하는지 말할 수 것 같습니다.Get-Content새로운 내용을 보여드리려는데 잘못 해석하셨을 겁니다.

를 감시하고 것 Last Modified소유물.문제는 이 속성을 포함하는 NTFS 메타데이터가 "성능상의 이유로" 특정 상황을 제외하고는 자동으로 업데이트되지 않는다는 것입니다.

파일 핸들이 닫혀 있는 경우(따라서 @Duncan의 관찰)가 있습니다.다른 하나는 파일의 정보를 직접 쿼리하는 경우이므로 질문에 언급된 탐색기 새로 고침 동작입니다.

이 Powershell 할 수 .Get-Content -Wait것을 를 볼 수 있습니다.Last Modified열이 보입니다.하세요를 하세요.Last Modified파일이 수정되면 자동으로 업데이트되지 않습니다.

이제 다른 창에서 파일의 속성을 가져옵니다.예를 들어 명령 프롬프트에서type서류철 을 열고 단추로 단추로 만 하면 또는 동일한 폴더에서 다른 탐색기 창을 열고 파일을 마우스 오른쪽 단추로 클릭하여 속성을 가져옵니다(저는 마우스 오른쪽 단추로 클릭만 하면 됩니다). 첫 합니다.Last Modified컬럼과 파워셸이 업데이트를 감지하고 로그를 따라잡을 것입니다.,LastWriteTime속성으로 충분:

(Get-Item file.log).LastWriteTime = (Get-Item file.log).LastWriteTime

아니면

(Get-Item file.log).LastWriteTime = Get-Date

그래서 이제 이것이 저에게 효과가 있습니다.

Start-Job {
  $f=Get-Item full\path\to\log
  while (1) {
    $f.LastWriteTime = Get-Date
    Start-Sleep -Seconds 10
  }
}
Get-Content path\to\log -Wait

그것을 재현하는 방법을 알려주시겠습니까?

이 스크립트는 PS 세션 하나에서 시작할 수 있습니다.

get-content c:\testfiles\test1.txt -wait

그리고 이것은 또 다른 세션에서:

while (1){
get-date | add-content c:\tesetfiles\test1.txt 
Start-Sleep -Milliseconds 500
}

그리고 첫 번째 세션에서 새로운 항목이 작성되는 것을 봅니다.

get-content는 window api를 거치는 경우에만 작동하는 것으로 보이며 파일에 첨부하는 버전이 다릅니다.

program.exe > output.txt

그리고 나서.

get-content output.txt -wait

업데이트되지 않습니다. 하지만.

program.exe | add-content output.txt

함께 작업할 것입니다.

get-content output.txt -wait    

그래서 애플리케이션이 어떻게 출력되느냐에 따라 다를 것 같습니다.

Get-Content -Wait은(는) 매초 새로 고침을 수행하며 디스크에서 파일이 변경될 때 변경 내용을 보여줍니다.뭐가 뭔지 모르겠어요.tail -f다른 방식으로 진행되고 있지만, 설명을 토대로 볼 때 이 문제는 PowerShell이 아니라 쓰기 캐싱에 관한 것이라고 확신합니다. log4net만, OS다,다 두 로 OS 캐싱이

  1. log4j/log4net 설명서에는 기본적으로 모든 추가 작업 후 버퍼를 플러시한다고 나와 있으며, 만약 당신이 모든 추가 작업 후에 버퍼를 플러시하지 않도록 명시적으로 구성했다면, 당신은 그것을 알고 있을 것이라고 추측합니다.
  2. Windows 탐색기를 새로 고치면 디렉토리에 있는 파일이 변경된 경우 쓰기 버퍼 플러시가 발생한다는 사실을 알고 있습니다.그것은 메타데이터만이 아니라 파일 내용을 실제로 읽어서 썸네일이나 미리보기와 같은 확장된 정보를 제공하고, 읽기 작업으로 인해 쓰기 버퍼가 플러시되기 때문입니다.따라서 Windows 탐색기에서 로그 파일의 디렉토리를 새로 고칠 때마다 업데이트가 지연되는 경우 이 방향을 강하게 가리킵니다.

시도해 보기:장치 관리자를 열고 디스크 드라이브 노드를 확장한 다음 로그 파일이 저장된 디스크의 속성을 열고 정책 탭으로 전환한 다음 장치에서 쓰기 캐싱 사용을 선택 취소합니다.당신은 그것을 발견할 겁니다.Get-Content -Wait이제 변경사항이 발생했을 때의 모습을 보여드리겠습니다.

tail -f변화된 내용을 그대로 보여주고 있습니다만, 추측할 수밖에 없습니다. 이 하거나 Cygwin하는 동안 플러시를 수 있습니다.tail -f, 바로 이 문제를 해결하기 위해서입니다.


업데이트:

Duncan 에 이 의.Get-Content -Wait파일을 닫을 때까지 문서와 달리 새 결과를 출력하지 않습니다.

그러나 이미 구축된 정보와 추가 테스트를 바탕으로 파일이 닫힐 때까지 기다리지 않고 파일에 추가된 새로운 데이터를 디스크에 쓰는 즉시 출력하며 OP가 보고 있는 문제는 거의 확실하게 쓰기 버퍼링 때문이라는 것을 결정적으로 확인했습니다.

이를 증명하기 위해 사실을 허심탄회하게 세상에 제출해야 합니다.

  • 했습니다를 했습니다.Get-Content -Waitxlsx 파일을 기준으로 합니다.에 새 Get-Content -Wait는 새로운 정보가 RAM에만 있고 디스크에는 없는 동안 예상되는 새로운 출력을 생성하지 않았습니다.그러나 데이터를 추가한 후 스프레드시트를 저장할 때마다 바로 새로운 출력이 생성되었습니다.

    파일을 저장할 때 엑셀은 파일을 닫지 않습니다.파일은 Excel에서 Window를 닫거나 Excel을 종료할 때까지 열려 있습니다.Excel에서 창이 열려 있는 동안 저장한 후 .xlsx 파일을 삭제하거나 이름을 바꾸거나 수정하여 이를 확인할 수 있습니다.

  • OP는 윈도우 탐색기에서 폴더를 새로 고치면 새로운 출력이 나온다고 말했습니다.폴더 목록을 새로 고친다고 해서 파일이 닫히지는 않습니다.파일이 변경된 경우 쓰기 버퍼를 플러시합니다.파일의 속성을 읽어야 하기 때문에 이 작업은 쓰기 버퍼를 플러시하기 때문입니다.이에 대한 참고 자료를 찾아 보겠지만, 위에서 언급했듯이 이것이 사실이라는 것을 알고 있습니다.

  • 상황을 는 50의 이 1,000번의 던컨의 테스트 의했습니다를 정확히 하는 할 수 과 같은 수정 동작을 했습니다.Get-Content -Wait이 있습니다.다.

    1..1000 | %{"${_}: Write $(Get-Date -Format "hh:mm:ss")"; Write-Host -NoNewline "$_..."; Start-Sleep 1} > .\gcwtest.txt
    

    이 일이 진행되는 동안, 저는 뛰었습니다.Get-Content -Wait .\gcwtest.txt다른 창에서, 윈도우 탐색기에서 디렉토리를 열었습니다.새로 고침을 수행하면 KB의 파일 크기가 변경될 때마다 출력이 더 많이 생성되고, 눈에 보이는 것이 없더라도 항상 그렇지는 않다는 것을 알 수 있었습니다. (나중에 이러한 불일치가 미치는 영향에 대한 자세한 내용은...)

  • 한 테스트를세 PowerShell 했습니다에서 과 같은 모든 을 확인했습니다.Get-Content -Wait목록:

    • 을 기존 하는 중Get-Content .\gcwtest.txt

    • 파일의 특성을 읽는 중입니다.그러나 변경되지 않는 특성의 경우 첫 번째 읽기만 업데이트를 트리거합니다.

      를 들면, ,(gi .\gcwtest.txt).lastwritetime더 많은 출력을 여러 번 트리거합니다.에.(gi .\gcwtest.txt).mode아니면(gi .\gcwtest.txt).directory첫 번째로 더 많은 출력을 트리거하지만 반복하는 경우에는 트리거하지 않습니다.또한 다음 사항에 유의합니다.

      »  이 동작은 100% 일치하지 않습니다.모드 또는 디렉토리를 읽어도 처음에 더 많은 출력이 트리거되지 않는 경우가 있지만, 작업을 반복하면 트리거됩니다.업데이트된 출력을 트리거하는 첫 번째 반복 이후의 모든 후속 반복은 영향을 미치지 않습니다.

      »  테스트를 반복하면 파이프라인을 다시 실행하기 전에 .txt 파일을 삭제하지 않는 한 동일한 속성을 읽어도 출력이 트리거되지 않습니다.사실, 때로는 심지어(gi .\gcwtest.txt).lastwritetimegcwtest를 삭제하지 않고 테스트를 반복하면 더 많은 출력을 트리거하지 않습니다.txt.

      »  발행하는 경우(gi .\gcwtest.txt).lastwritetime1초 동안 여러 번, 첫 번째 하나만 출력을 트리거합니다. 즉, 결과가 변경된 경우에만 출력을 트리거합니다.

    • 텍스트 편집기에서 파일을 엽니다.연로 유지하는 하는 경우 않음하지 않고 우음)이 을 알 수 Get-Content -Wait편집기에서 파일을 연 이후 파이프라인에서 추가된 줄을 출력합니다.

    • 탭 - 파일 이름 완성

  • 중 몇번해 보면 많은 그 합니다를 하게 됩니다.Get-Content -Wait파이프라인 실행의 나머지 부분에 대해 주기적으로 더 많은 라인을 출력합니다.한 번에 한 줄이 아니라, 묶음으로.

  • 행동 자체의 불일치는 버퍼 플러싱(buffer flushing)을 가리키는데, 버퍼 플러싱은 예측하기 어려운 변수 기준에 따라 발생하지만, 폐쇄는 명확하고 일관된 상황에서 발생합니다.

결론: Get-Content -Wait광고대로 작동합니다.디스크의* 파일에 물리적으로 쓰임과 동시에 새 내용이 표시됩니다.

It should be noted that my suggestion to disable write caching on the drive did 것은 아니다. for the test above, i.e. it did not result in `Get-Content -Wait displaying new lines as soon as they're added to the text file by the pipeline, so perhaps the buffering responsible for the output latency is occurring on a filesystem or OS level as opposed to the disk's write cache. However, write buffering is clearly the explanation for the behavior observed in the OP's question.

는 하지 의 범위를 벗어났기 말이죠 하지만 * 만,Get-Content -Wait파일 끝에 내용을 추가하지 않으면 이상하게 동작합니다.파일 끝의 데이터를 추가된 데이터의 크기와 동일하게 표시합니다.새로 표시되는 데이터는 일반적으로 이전에 표시되었던 데이터를 반복하며, 새 데이터의 크기가 다음에 표시되는 데이터의 크기를 초과하는지 여부에 따라 새 데이터를 포함할 수도 있고 포함하지 않을 수도 있습니다.

WindowsUpdate.log를 실시간으로 보려고 하다가 같은 문제가 발생했습니다.이상적이지는 않지만 아래 코드를 통해 진행 상황을 확인할 수 있습니다. -위에서 설명한 동일한 파일 작성 제한 사항으로 인해 Wait가 작동하지 않았습니다.

마지막 10줄을 표시하고 10초 동안 절전 모드로 전환한 후 화면을 지우고 마지막 10줄을 다시 표시합니다.Ctrl + C로 스트림을 중지합니다.

 while(1){
Get-Content C:\Windows\WindowsUpdate.log -tail 10 
    Start-Sleep -Seconds 10
    Clear 
    }

언급URL : https://stackoverflow.com/questions/19919180/get-content-wait-not-working-as-described-in-the-documentation

반응형