当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 关于重定向

作者:精品下载站 日期:2024-12-14 02:19:32 浏览:14 分类:玩电脑

关于重定向


简短描述

解释如何将输出从 PowerShell 重定向到文本文件。

详细描述

默认情况下,PowerShell 将输出发送到 PowerShell 主机。通常这是控制台应用程序。但是,您可以将输出重定向到文本文件,并且可以将错误输出重定向到常规输出流。

您可以使用以下方法来重定向输出:

  • 使用 Out-File cmdlet,它将命令输出发送到文本文件。通常,当您需要使用 Out-File cmdlet 的参数(例如 EncodingForceWidthNoClobber 参数。

  • 使用 Tee-Object cmdlet,它将命令输出发送到文本文件,然后将其发送到管道。

  • 使用 PowerShell 重定向运算符。使用重定向运算符 (>) 重定向 PowerShell 命令(cmdlet、函数、脚本)的输出在功能上等同于通过管道传输到 Out-File,无需额外参数。 PowerShell 7.4 更改了重定向运算符在用于重定向本机命令的 stdout 流时的行为。

有关流的更多信息,请参阅 about_Output_Streams。

可重定向的输出流

PowerShell 支持以下输出流的重定向。

Stream # Description Introduced in Write Cmdlet 1 Success Stream PowerShell 2.0 Write-Output 2 Error Stream PowerShell 2.0 Write-Error 3 Warning Stream PowerShell 3.0 Write-Warning 4 Verbose Stream PowerShell 3.0 Write-Verbose 5 Debug Stream PowerShell 3.0 Write-Debug 6 Information Stream PowerShell 5.0 Write-Information, Write-Host * All Streams PowerShell 3.0

PowerShell 中还有一个 Progress 流,但它不支持重定向。

这很重要

SuccessError 流与其他 shell 的 stdout 和 stderr 流类似。但是,stdin 未连接到 PowerShell 管道以进行输入。

PowerShell 重定向运算符

PowerShell 重定向运算符如下,其中 n 表示流编号。如果未指定流,则默认为 Success 流 ( 1 )。

Operator Description Syntax > Send specified stream to a file. n> >> Append specified stream to a file. n>> >&1 Redirects the specified stream to the Success stream. n>&1

笔记

与某些 Unix shell 不同,您只能将其他流重定向到 Success 流。

重定向本机命令的输出

PowerShell 7.4 更改了重定向运算符在用于重定向本机命令的 stdout 流时的行为。现在,重定向运算符在重定向本机命令的输出时会保留字节流数据。 PowerShell 不会解释重定向的数据或添加任何其他格式。有关更多信息,请参见示例#7。

示例

示例 1:将错误重定向并输出到文件

此示例对一项成功的项目和一项失败的项目运行 dir

dir C:\, fakepath 2>&1 > .\dir.log

它使用 2>&1Error 流重定向到 Success 流,并使用 > 发送结果 成功流到名为dir.log的文件

示例 2:将所有 Success 流数据发送到文件

此示例将所有 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>&1Warning 流重定向到 Success 流。
  • 2>&1Error 流重定向到 Success 流(现在还包括所有 Warning 流数据)
  • >Success 流(现在包含 WarningError 流)重定向到名为 的文件C:\temp\redirection.log

示例 4:将所有流重定向到文件

此示例将名为 script.ps1 的脚本的所有流输出发送到名为 script.log 的文件。

.\script.ps1 *> script.log

示例 5:抑制所有 Write-Host 和信息流数据

该示例抑制所有信息流数据。要了解有关信息流 cmdlet 的更多信息,请参阅 Write-Host 和 Write-Information

&{
   Write-Host "Hello"
   Write-Information "Hello" -InformationAction Continue
} 6> $null

示例 6:显示 Action Preferences 的效果

操作首选项变量和参数可以更改写入特定流的内容。此示例中的脚本显示了 $ErrorActionPreference 的值如何影响写入 Error 流的内容。

$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'

当我们运行此脚本时,当 $ErrorActionPreference 设置为 Inquire 时,我们会收到提示。

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 开始,当将本机命令的 stdout 流重定向到文件或将字节流数据通过管道传输到命令的 stdin 流时,PowerShell 会保留字节流数据。本机命令。

例如,使用本机命令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 时,此功能不支持字节流数据。当您组合 stderrstdout 流时,组合后的流将被视为字符串数据。

笔记

不附加数据的重定向运算符(>n>)会覆盖指定文件的当前内容,而不发出警告。

但是,如果文件是只读文件、隐藏文件或系统文件,则重定向失败。附加重定向运算符(>>n>>)不会写入只读文件,但它们会将内容附加到系统或隐藏文件。

要强制将内容重定向到只读、隐藏或系统文件,请使用 Out-File cmdlet 及其 Force 参数。

当您写入文件时,重定向运算符使用 UTF8NoBOM 编码。如果文件具有不同的编码,则输出的格式可能不正确。要写入具有不同编码的文件,请使用 Out-File cmdlet 及其 Encoding 参数。

写入文件时输出的宽度

当您使用 Out-File 或重定向运算符写入文件时,PowerShell 会根据运行的控制台的宽度将表输出格式化为文件。例如,在控制台宽度设置为 80 列的系统上使用诸如 Get-ChildItem Env:\Path > path.log 之类的命令将表输出记录到文件时,文件中的输出为被截断为 80 个字符:

Name                         Value
----                         -----
Path                         C:\Program Files\PowerShell;C:\WINDOWS…

考虑到控制台宽度可以在运行脚本的系统上任意设置,您可能更喜欢 PowerShell 根据您指定的宽度将表输出格式化为文件。

Out-File cmdlet 提供了一个Width 参数,允许您设置表输出所需的宽度。您可以使用 $PSDefaultParameterValues 变量为所有用途设置此值,而不必在调用 Out-File 的任何地方添加 -Width 2000脚本中的 Out-File cmdlet。由于重定向运算符(>>>)实际上是 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。有关详细信息,请参阅 about_Comparison_Operators 中的 -gt 运算符。

参见

  • about_Command_Syntax
  • about_Operators
  • about_Output_Streams
  • about_Path_Syntax
  • Out-File
  • Tee-Object
  • Write-Debug
  • Write-Error
  • Write-Host
  • Write-Information
  • Write-Output
  • Write-Progress
  • Write-Verbose
  • Write-Warning

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯