2012-01-19 40 views
31

Tôi cần thu thập đầu ra tiêu chuẩn và nhật ký lỗi từ một số quy trình vào một tệp nhật ký duy nhất.Chuyển hướng đầu ra tiêu chuẩn và lỗi gắn vào cùng một tệp nhật ký

Vì vậy, mọi đầu ra phải nối thêm vào logfile này.

Tôi muốn gọi tất cả các công việc với các dòng như thế này:

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

Nơi nào tôi phải đưa các thông tin để nối thêm?

Trả lời

52

Để thêm vào tệp bạn cần sử dụng phương pháp hơi khác. Bạn vẫn có thể chuyển hướng một quá trình cá nhân sai số chuẩn và đầu ra tiêu chuẩn để nộp nhưng để gắn nó vào một tập tin bạn sẽ cần phải làm một trong những điều sau:

  1. Đọc nội dung tập tin stdout/stderr tạo ra bởi Start-Process
  2. Không sử dụng Start-Quy trình và sử dụng toán tử gọi &
  3. Không sử dụng Start-Quy trình và bắt đầu quá trình với các đối tượng .NET

cách thứ nhất sẽ trông như thế này:

$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 

Cách thứ hai sẽ trông như thế này:

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

Hoặc này:

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

Cách thứ ba:

$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

Great câu trả lời. Nhưng có vẻ như với tôi rằng có một lỗi trong cách đầu tiên. Thay vì -errirectoutput tôi nghĩ rằng nó phải là -RedirectStandardError. – Grigory

+3

Bắt tốt! Đã sửa lỗi :-) –

+0

Nó có hoạt động cho Powershell Remoting không? Tôi đã thử nghiệm, tôi nghĩ rằng chỉ có cách thứ hai hoạt động cho PS Remoting. – Kiquenet

0

Có lẽ không phải là khá thanh lịch. Nhưng điều này cũng sẽ làm việc? Tôi nghi ngờ không đồng bộ này sẽ không phải là một giải pháp tốt.

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

Nó không thực sự hoạt động vì Powershell không cho phép bạn chuyển hướng standardput và redirecterroroutput sang cùng một tệp. "Start-Process: Lệnh này không thể chạy vì" RedirectStandardOutput "và" RedirectStandardError "giống nhau. Cho các đầu vào khác nhau và chạy lại lệnh của bạn." là lỗi tôi nhận được khi tôi thử. – Bob

14

Andy đã cho tôi một số gợi ý tốt, nhưng tôi muốn làm điều đó một cách rõ ràng hơn. Chưa kể rằng với phương pháp 2>&1 >>, PowerShell đã phàn nàn với tôi về tệp nhật ký đang được truy cập bởi một quy trình khác, tức là cả stderr và stdout đang cố khóa tệp để truy cập, tôi đoán vậy. Vì vậy, đây là cách tôi làm việc xung quanh.

Đầu tiên chúng ta hãy tạo ra một tên tập tin tốt đẹp, nhưng đó là thực sự chỉ vì đã pedantic:

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

Và đây là nơi lừa bắt đầu:

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 

Với start-transcriptstop-transcript bạn có thể chuyển hướng tất cả sản lượng của Lệnh PowerShell vào một tệp, nhưng it doesn't work correctly with external commands. Vì vậy, chúng ta hãy chuyển hướng tất cả các đầu ra của những người đến stdout của PS và để cho bảng điểm làm phần còn lại. Trong thực tế, tôi không biết tại sao các kỹ sư MS nói rằng họ chưa sửa lỗi này "do chi phí cao và phức tạp kỹ thuật liên quan" khi nó có thể được làm việc xung quanh một cách đơn giản như vậy. "Cả hai cách, chạy mọi lệnh đơn lẻ với start-process là một IMHO lộn xộn rất lớn, nhưng với phương pháp này, tất cả những gì bạn phải làm là nối thêm mã 2>&1 | Write-Output vào mỗi dòng chạy các lệnh bên ngoài.

+0

Câu trả lời hay nhất cho vấn đề. Cảm ơn! –

12

vỏ Giống như Unix, Powershell hỗ trợ > chuyển hướng với hầu hết các biến thể được biết đến từ Unix, bao gồm 2>&1 (mặc dù thật là thú vị, trật tự không quan trọng - 2>&1 > file hoạt động giống như bình thường > file 2>&1).

Giống như hầu hết các vỏ Unix hiện đại, Powershell cũng có phím tắt để chuyển hướng cả stderr và stdout sang cùng một thiết bị, mặc dù không giống như các phím tắt chuyển hướng khác tuân theo quy ước Unix. như vậy: *>.

Vì vậy, thực hiện của bạn có thể là:

& myjob.bat *>> $logfile 
Các vấn đề liên quan