about_Redirection
簡短描述
說明如何將PowerShell的輸出重新導向至文字檔。
詳細描述
根據預設,PowerShell 會將輸出傳送至 PowerShell 主機。 這通常是主控台應用程式。 不過,您可以將輸出重新導向至文本檔,並將錯誤輸出重新導向至一般輸出數據流。
您可以使用下列方法來重新導向輸出:
Out-File
使用 Cmdlet,它會將命令輸出傳送至文字檔。 一般而言,當您Out-File
需要使用 Cmdlet 參數時,請使用 Cmdlet,例如Encoding
、Force
、Width
或NoClobber
參數。Tee-Object
使用 Cmdlet,將命令輸出傳送至文本文件,然後將它傳送至管線。使用 PowerShell 重新導向運算子。 使用重新導向運算子 (
>
) 重新導向 PowerShell 命令的輸出 (Cmdlet, 函式, 腳本) 的功能相當於管線Out-File
,而不需要額外的參數。 PowerShell 7.4 在用來重新導向原生命令的 stdout 數據流時,已變更重新導向運算符的行為。
如需數據流的詳細資訊,請參閱 about_Output_Streams。
可重新導向的輸出數據流
PowerShell 支援下列輸出數據流的重新導向。
流# | 描述 | 中引進 | 寫入 Cmdlet |
---|---|---|---|
1 | 成功 串流 | PowerShell 2.0 | Write-Output |
2 | 錯誤 數據流 | PowerShell 2.0 | Write-Error |
3 | 警告 數據流 | PowerShell 3.0 | Write-Warning |
4 | 詳細資訊串流 | PowerShell 3.0 | Write-Verbose |
5 | 偵錯 數據流 | PowerShell 3.0 | Write-Debug |
6 | 資訊 串流 | PowerShell 5.0 | Write-Information , Write-Host |
* | 所有數據流 | PowerShell 3.0 |
PowerShell 中也有 進度 數據流,但不支援重新導向。
重要
成功和錯誤數據流類似於其他殼層的 stdout 和 stderr 數據流。 不過,stdin 未連線到 PowerShell 管線以進行輸入。
PowerShell 重新導向運算符
PowerShell 重新導向運算符如下所示,其中 n
代表數據流編號。 如果未指定任何數據流,則成功數據流 ( 1
) 是預設值。
運算子 | 描述 | 語法 |
---|---|---|
> |
將指定的數據流傳送至檔案。 | n> |
>> |
將指定的數據流附加 至檔案。 | n>> |
>&1 |
將 指定的數據流重新導向至 成功 數據流。 | n>&1 |
注意
不同於某些 Unix 殼層,您只能將其他數據流重新導向至 成功 數據流。
從原生命令重新導向輸出
PowerShell 7.4 在用來重新導向原生命令 stdout 數據流時,已變更重新導向運算符的行為。 重新導向運算子現在會在從原生命令重新導向輸出時保留位元組數據流數據。 PowerShell 不會解譯重新導向的數據或新增任何其他格式。 如需詳細資訊,請參閱 範例 #7。
範例
範例 1:將錯誤和輸出重新導向至檔案
這個範例會在一個成功的專案上執行 dir
,另一個項目會失敗。
dir C:\, fakepath 2>&1 > .\dir.log
它會使用 2>&1
將錯誤數據流重新導向至成功數據流,並將>
產生的 Success 數據流傳送至名為 的檔案dir.log
範例 2:將所有成功串流數據傳送至檔案
此範例會將所有 Success 數據流數據傳送至名為 的 script.log
檔案。
.\script.ps1 > script.log
範例 3:將成功、警告和錯誤數據流傳送至檔案
此範例示範如何結合重新導向運算符來達成所需的結果。
&{
Write-Warning "hello"
Write-Error "hello"
Write-Output "hi"
} 3>&1 2>&1 > C:\Temp\redirection.log
3>&1
會將警告數據流重新導向至成功數據流。2>&1
將 錯誤 資料流重新導向至 成功 資料流(現在也包含所有 警告 資料串流資料 )>
將 成功 資料流 (現在同時 包含警告 和 錯誤 資料流) 重新導向至名為C:\temp\redirection.log
的檔案。
範例 4:將所有數據流重新導向至檔案
此範例會將呼叫 之腳本 script.ps1
的所有數據流輸出傳送至名為 script.log
的檔案。
.\script.ps1 *> script.log
範例 5:隱藏所有寫入主機和資訊數據流數據
此範例會隱藏所有資訊數據流數據。 若要深入瞭解 信息 數據流 Cmdlet,請參閱 Write-Host 和 Write-Information
&{
Write-Host "Hello"
Write-Information "Hello" -InformationAction Continue
} 6> $null
範例 6:顯示動作喜好設定的效果
動作喜好設定變數和參數可以變更寫入特定數據流的內容。 此範例中的腳本會示範的值$ErrorActionPreference
如何影響寫入錯誤數據流的內容。
$ErrorActionPreference = 'Continue'
$ErrorActionPreference > log.txt
get-item /not-here 2>&1 >> log.txt
$ErrorActionPreference = 'SilentlyContinue'
$ErrorActionPreference >> log.txt
get-item /not-here 2>&1 >> log.txt
$ErrorActionPreference = 'Stop'
$ErrorActionPreference >> log.txt
Try {
get-item /not-here 2>&1 >> log.txt
}
catch {
"`tError caught!" >> log.txt
}
$ErrorActionPreference = 'Ignore'
$ErrorActionPreference >> log.txt
get-item /not-here 2>&1 >> log.txt
$ErrorActionPreference = 'Inquire'
$ErrorActionPreference >> log.txt
get-item /not-here 2>&1 >> log.txt
$ErrorActionPreference = 'Continue'
當我們執行此腳本時,系統會在 設定為 Inquire
時$ErrorActionPreference
收到提示。
PS C:\temp> .\test.ps1
Confirm
Can't find path 'C:\not-here' because it doesn't exist.
[Y] Yes [A] Yes to All [H] Halt Command [S] Suspend [?] Help (default is "Y"): H
Get-Item: C:\temp\test.ps1:23
Line |
23 | get-item /not-here 2>&1 >> log.txt
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| The running command stopped because the user selected the Stop option.
當我們檢查記錄檔時,我們會看到下列內容:
PS C:\temp> Get-Content .\log.txt
Continue
Get-Item: C:\temp\test.ps1:3
Line |
3 | get-item /not-here 2>&1 >> log.txt
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Cannot find path 'C:\not-here' because it does not exist.
SilentlyContinue
Stop
Error caught!
Ignore
Inquire
範例 7:從原生命令重新導向二進位數據
從 PowerShell 7.4 開始,PowerShell 會將原生命令的 stdout 數據流重新導向至檔案,或將位元組數據流數據傳送至原生命令的 stdin 數據流時,保留位元組數據流數據。
例如,使用原生命令 curl
,您可以下載二進位檔,並使用重新導向將它儲存到磁碟。
$uri = 'https://github.com/PowerShell/PowerShell/releases/download/v7.3.7/powershell-7.3.7-linux-arm64.tar.gz'
# native command redirected to a file
curl -s -L $uri > powershell.tar.gz
您也可以使用管線將位元組數據流數據傳送至 另一個原生命令的 stdin 數據流。 下列範例會使用 curl
下載壓縮的 TAR 檔案。
下載的檔案數據會串流至 命令, tar
以擷取封存的內容。
# native command output piped to a native command
curl -s -L $uri | tar -xzvf - -C .
您也可以使用管線將PowerShell命令的位元組資料流輸出傳送至原生命令的輸入。 下列範例會使用 Invoke-WebRequest
來下載與上一個範例相同的 TAR 檔案。
# byte stream piped to a native command
(Invoke-WebRequest $uri).Content | tar -xzvf - -C .
# bytes piped to a native command (all at once as byte[])
,(Invoke-WebRequest $uri).Content | tar -xzvf - -C .
將 stderr 輸出重新導向至 stdout 時,此功能不支援位元組數據流數據。 當您合併 stderr 和 stdout 數據流時,合併的數據流會被視為字串數據。
備註
未附加數據的重新導向運算符 (>
和 n>
) 會覆寫指定檔案的目前內容,而不會發出警告。
不過,如果檔案是唯讀、隱藏或系統檔案,則重新導向 會失敗。 附加重新導向運算符 (>>
和 n>>
) 不會寫入唯讀檔案,但會將內容附加至系統或隱藏的檔案。
若要強制將內容重新導向至只讀、隱藏或系統檔案,請使用 Out-File
Cmdlet 搭配其 Force
參數。
當您寫入檔案時,重新導向運算子會使用 UTF8NoBOM
編碼。 如果檔案有不同的編碼方式,則輸出可能無法正確格式化。 若要以不同的編碼方式寫入檔案,請使用 Out-File
Cmdlet 搭配其 Encoding
參數。
寫入檔案時的輸出寬度
當您使用 Out-File
或 重新導向運算符寫入檔案時,PowerShell 會根據執行中的主控台寬度,將資料表輸出格式化為檔案。 例如,使用類似 Get-ChildItem Env:\Path > path.log
主控台寬度設定為80個資料行之系統上的命令將資料表輸出記錄到檔案時,檔案中的輸出會截斷為80個字元:
Name Value
---- -----
Path C:\Program Files\PowerShell\7;C:\WINDOWS…
考慮到主控台寬度可能會在執行文本的系統上任意設定,您可能會偏好根據您指定的寬度,將 PowerShell 格式資料表輸出設定為檔案。
Cmdlet Out-File
提供 Width 參數,可讓您設定您想要用於資料表輸出的寬度。 您不必在叫用 的任何位置Out-File
新增 -Width 2000
,而是可以使用 $PSDefaultParameterValues
變數,針對腳本中 Cmdlet 的所有使用方式Out-File
設定此值。 由於 重新導向運算子 (>
和 >>
) 實際上是 的 Out-File
別名,因此 Out-File:Width
設定整個腳本的參數也會影響重新導向運算符的格式寬度。 將下列命令放在腳本頂端附近,以針對整個腳本進行設定 Out-File:Width
:
$PSDefaultParameterValues['out-file:width'] = 2000
當記錄數據表格式化輸出時,增加輸出寬度會增加記憶體耗用量。 如果您要將許多表格式數據記錄到檔案,而且您知道可以透過較小的寬度取得,請使用較小的寬度。
在某些情況下,例如 Get-Service
輸出,若要使用額外的寬度,您必須在輸出至檔案之前透過管線傳送輸出 Format-Table -AutoSize
。
$PSDefaultParameterValues['out-file:width'] = 2000
Get-Service | Format-Table -AutoSize > services.log
如需 的詳細資訊 $PSDefaultParameterValues
,請參閱 about_Preference_Variables。
比較運算子的潛在混淆
>
運算子不會與大於比較運算元混淆(通常如>
其他程序設計語言所示)。
視所比較的物件而定,使用 >
的輸出看起來可能正確(因為 36 不大於 42)。
PS> if (36 > 42) { "true" } else { "false" }
false
不過,本機檔案系統的檢查可以看到已寫入名為 42
的檔案,且內容為 36
。
PS> dir
Mode LastWriteTime Length Name
---- ------------- ------ ----
------ 1/02/20 10:10 am 3 42
PS> cat 42
36
嘗試使用反向比較 <
(小於),會產生系統錯誤:
PS> if (36 < 42) { "true" } else { "false" }
ParserError:
Line |
1 | if (36 < 42) { "true" } else { "false" }
| ~
| The '<' operator is reserved for future use.
如果數值比較是必要作業, -lt
則 -gt
應該使用 。 如需詳細資訊,請參閱 -gt
about_Comparison_Operators 中的運算符。