2012-01-19 16 views
31

Birkaç işlemden standart çıktı ve hata günlüğünü tek bir günlük dosyasına almam gerekir.Standart ve hata çıktısının aynı kayıt dosyasına eklenmesi Yönlendirme

Bu nedenle, her çıkış değerini bu günlük dosyasına ekleyecektir.

Böyle hatları ile tüm işleri çağırmak istiyorum: Ben eklemek için bilgileri koymak zorunda yapmak

$p=start-process myjob.bat -redirectstandardoutput $logfile -redirecterroroutput $logfile -wait 

?

cevap

52

Bir dosya eklemek için biraz farklı bir yaklaşım kullanmanız gerekir. Start-Process yarattığı

  1. Oku stdout/stderr dosya içeriğine: Hala bir birey süreçleri standart hata ve dosyaya standart çıktı ancak bunlardan birini yapmanız gerekir bir dosyaya eklemek için yönlendirebilir
  2. Start-süreci kullanmak ve Başlat-süreci kullanmamak çağrı operatöre &
  3. kullanmak ve .NET

birinci yol şu şekilde görünecektir nesneleri ile işlemini başlatmak değil:

şu şekilde görünecektir
$myLog = "C:\File.log" 
$stdErrLog = "C:\stderr.log" 
$stdOutLog = "C:\stdout.log" 
Start-Process -File myjob.bat -RedirectStandardOutput $stdOutLog -RedirectStandardError $stdErrLog -wait 
Get-Content $stdErrLog, $stdOutLog | Out-File $myLog -Append 

İkinci yol:

& myjob.bat 2>&1 >> C:\MyLog.txt 

Ya da bu:

& myjob.bat 2>&1 | Out-File C:\MyLog.txt -Append 

üçüncü yol: Belki

$pinfo = New-Object System.Diagnostics.ProcessStartInfo 
$pinfo.FileName = "myjob.bat" 
$pinfo.RedirectStandardError = $true 
$pinfo.RedirectStandardOutput = $true 
$pinfo.UseShellExecute = $false 
$pinfo.Arguments = "" 
$p = New-Object System.Diagnostics.Process 
$p.StartInfo = $pinfo 
$p.Start() | Out-Null 
$p.WaitForExit() 
$output = $p.StandardOutput.ReadToEnd() 
$output += $p.StandardError.ReadToEnd() 
$output | Out-File $myLog -Append 
+2

Güzel cevap. Ama bana göre ilk bakışta bir hata var. -Redirectterroroutput yerine -RedirectStandardError olması gerektiğini düşünüyorum. – Grigory

+3

İyi yakalama! Sabit :-) –

+0

Powershell Remoting için çalışıyor mu? Test ettim, sadece ikinci yöntem PS Remoting için çalışıyor. – Kiquenet

0

oldukça şık değil. Ama bu da işe yarayacak mı? Asenkronize olduğundan şüpheleniyorum, bu iyi bir çözüm olmazdı.

$p=start-process myjob.bat -redirectstandardoutput $logtempfile -redirecterroroutput $logtempfile -wait 
add-content $logfile (get-content $logtempfile) 
+0

Aslında çalışmaz, çünkü Powershell standart kayıt ve yeniden yönlendirmeyi aynı dosyaya yeniden yönlendirmenize izin vermez. "Start-Process:" RedirectStandardOutput "ve" RedirectStandardError "aynı olduğu için bu komut çalıştırılamıyor. Farklı girişler verin ve komutunuzu tekrar çalıştırın." Bunu denediğimde aldığım hata. – Bob

14

Andy bana iyi işaretçiler verdi ama ben daha derli toplu bir şekilde bunu yapmak istedim. PowerShell, 2>&1 >> yöntemiyle başka bir işlem tarafından erişilen günlük dosyası hakkında bana şikâyette bulunmadığından, yani hem stderr hem de stdout erişim için dosyayı kilitlemeye çalışırken, sanırım. İşte işte burada çalıştım.

İlk önce güzel bir dosya adı oluşturmak izin, ama bu sadece bilgiçlik olduğu için gerçekten: Eğer TÜM çıkışını yönlendirebilirsiniz stop-transcriptstart-transcript ile

start-transcript -append -path $logfile 

write-output "starting sync" 
robocopy /mir /copyall S:\common \\10.0.0.2\common 2>&1 | Write-Output 
some_other.exe /exeparams 2>&1 | Write-Output 
... 
write-output "ending sync" 

stop-transcript 

ve: hile nerede başladığını

$name = "sync_common" 
$currdate = get-date -f yyyy-MM-dd 
$logfile = "c:\scripts\$name\log\$name-$currdate.txt" 

Ve burada PowerShell, tek bir dosyaya komut verir, ancak it doesn't work correctly with external commands. Öyleyse bunların tüm çıktılarını PS'nin stdout'una yönlendirelim ve transkript gerisini halledelim. Aslında, MS mühendislerinin neden bu kadar basit bir şekilde çalışılabileceğine dair "yüksek maliyet ve teknik karmaşıklıklar nedeniyle" bunu henüz düzeltmediklerini söyledikleri hakkında hiçbir fikrim yok.

Her iki yol da her bir komutu start-process ile çalıştırmak büyük bir karmaşama IMHO'dur, ancak bu yöntemle yapmanız gereken tek şey, harici komutları çalıştıran her satıra 2>&1 | Write-Output kodunu eklemektir.

+0

Sorunun en iyi cevabı. Teşekkürler! –

12

gibi Unix kabukları, Powershell > dahil Unix bilinen varyasyonların çoğunun ile yönlendirmelerini destekliyorsa 2>&1 (esrarlı, sırası önemli değildir gerçi - sadece normal > file 2>&1 gibi 2>&1 > file işleri).

Pek çok modern Unix kabuğunda olduğu gibi, Powershell aynı zamanda hem stderr hem de stdout'u aynı cihaza yönlendirmek için bir kısayol içeriyor, ancak Unix kongresini takip eden diğer yönlendirme kısayollarından farklı olarak, yakalama tüm kısayollar yeni bir sigil kullanıyor ve yazılıyor. böyle: *>.

Yani uygulama olabilir:

& myjob.bat *>> $logfile 
İlgili konular