2015-06-09 7 views
5

Sto usando PowerShell per scrivere e leggere i file di registro.Get-Content -Wait blocca il file mentre lo legge, impedendo al contenuto aggiuntivo di scrivere i dati

Uno script sta generando un file di registro con Aggiungi contenuto. Un altro script sta accodando il file di registro, usando Get-Content -Wait. Sembra che dovrebbe essere abbastanza affidabile.

Tuttavia, lo scrittore è spesso incapace di scrivere, e il lettore non è spesso in grado di leggere e si arrende. Posso solo supporre che questi due comandi non stiano aprendo il file con i flag di accesso appropriati e quindi si stanno combattendo a vicenda.

Ecco un piccolo script brutto che illustra il problema con due posti di lavoro nello stesso processo, anche se lo stesso accade tra i diversi processi 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 

Sulla mia macchina Windows 7 x64 con PowerShell 3 ISE, io di solito ottenere un sacco di errori di scrittura:

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 

E poi il file in lettura ha lacune in esso:

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

NB questo è un problema diverso da quello qui discusso: Get-Content -wait not working as described in the documentation e qui: 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 che riguardano la chiusura di un file che non viene chiuso tra una scrittura e l'altra.

C'è un modo per utilizzare Get-Content e Aggiungi-Contenuto come questo, o dovrei rinunciare, e usare qualcos'altro per leggere e scrivere i miei file di registro?

risposta

2

Provare a utilizzare Out-File invece di Add-Content

Sostituire

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

Con:

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

È necessario specificare codifica ASCII con Out-File se è quello che si voglio, poiché è l'impostazione predefinita per il contenuto aggiuntivo, ma non l'impostazione predefinita per il file esterno. È inoltre necessario utilizzare -append e/o -noclobber per evitare di sovrascrivere il contenuto del file esistente.

+0

Un aggiramento sarebbe di fare una copia del file e leggere che, invece, sospetto che forse la velocità con cui lo sta facendo in modo da poter inserire un sonno di inizio pure –

+0

@Nick Fare una copia del il file soffre dello stesso problema: può entrare in conflitto con il contenuto aggiuntivo, causando il fallimento della scrittura. Questo approccio non ha anche la semantica Wait che è la ragione per usare Get-Content. c.f. coda in bash. I posti letto non sono una soluzione, riducono solo la probabilità di un problema, rendendo più difficile trovarli nei test, ma altrettanto dannosi nella produzione. – ben

+1

@campbell Out-File fa il trucco. Questo sembra un bug (o almeno una caratteristica mancante) in Add-Content, una trappola per cui gli sceneggiatori non abituali devono cadere. Aggiungi contenuto considerato dannoso? – ben

Problemi correlati