在 shell 中运行命令

PowerShell 是命令行 shell 和用于自动化的脚本语言。 与其他 shell 类似,例如 Linux 上的 bash 或 Windows Command Shell(cmd.exe),PowerShell 允许你运行系统上可用的任何命令,而不仅仅是 PowerShell 命令。

命令类型

对于任何操作系统中的任何 shell,有三种类型的命令:

  • Shell 语言关键字 是 shell 脚本语言的一部分。

    • bash 关键字的示例包括:ifthenelseeliffi
    • cmd.exe 关键字的示例包括:dircopymoveifecho
    • PowerShell 关键字的示例包括:forforeachtrycatchtrap

    Shell 语言关键字只能在 shell 的运行时环境中使用。 shell 外部没有提供关键字功能的可执行文件。

  • 操作系统本机命令 是操作系统中安装的可执行文件。 可执行文件可以从任何命令行 shell(如 PowerShell)运行。 这包括可能需要其他 shell 才能正常运行的脚本文件。 例如,如果在 PowerShell 中运行 Windows 批处理脚本(.cmd 文件),PowerShell 将运行 cmd.exe 并传入批处理文件以供执行。

  • shell 环境特定的命令 是在外部文件中定义的命令,这些命令只能在 shell 的运行时环境中使用。 其中包括脚本和函数,也可以是专门编译的模块,用于将命令添加到 shell 运行时。 在 PowerShell 中,这些命令称为 cmdlet(发音为“command-lets”)。

运行本机命令

任何本机命令都可以从 PowerShell 命令行运行。 通常,运行命令的方式与 bashcmd.exe完全相同。 以下示例演示如何在 Ubuntu Linux 上的 grep 中运行 bash 命令。

sdwheeler@circumflex:~$ grep sdwheeler /etc/passwd
sdwheeler:x:1000:1000:,,,:/home/sdwheeler:/bin/bash
sdwheeler@circumflex:~$ pwsh
PowerShell 7.2.6
Copyright (c) Microsoft Corporation.

https://aka.ms/powershell
Type 'help' to get help.

在 Ubuntu 上启动 PowerShell 后,可以从 PowerShell 命令行运行相同的命令:

PS /home/sdwheeler> grep sdwheeler /etc/passwd
sdwheeler:x:1000:1000:,,,:/home/sdwheeler:/bin/bash

将参数传递给原生命令

大多数 shell 都包含用于使用变量、计算表达式和处理字符串的功能。 但每个 shell 都以不同的方式执行这些操作。 在 PowerShell 中,所有参数都以连字符(-)字符开头。 在 cmd.exe中,大多数参数都使用斜杠(/)字符。 其他命令行工具可能没有参数的特殊字符。

每个 shell 都有自己的命令行处理和评估字符串的方式。 在 PowerShell 中运行需要以特定方式引用字符串的本机命令时,可能需要调整传递这些字符串的方式。

有关详细信息,请参阅以下文章:

PowerShell 7.2 引入了一项新的实验性功能,PSNativeCommandArgumentPassing 改进了本机命令处理。 有关详细信息,请参阅 $PSNativeCommandArgumentPassing

处理输出和错误

PowerShell 的输出流数也多于其他 shell。 这 bashcmd.exe 贝壳有 stdoutstderr. PowerShell 有六个输出流。 有关详细信息,请参阅 about_Redirectionabout_Output_Streams

通常,通过本机命令发送到 stdout 的输出会发送到 PowerShell 中的 Success 流。 通过本机命令发送到 stderr 的输出会发送到 PowerShell 中的 Error 流。

当本机命令包含非零的退出代码时,$? 会设置为 $false。 如果退出代码为零,则 $? 设置为 $true

但是,这在 PowerShell 7.2 中已更改。 从本机命令重定向的错误记录(如使用重定向运算符(2>&1)时不会写入 PowerShell 的 $Error 变量,首选项变量 $ErrorActionPreference 不会影响重定向的输出。

许多本机命令写入 stderr 作为获取更多信息的替代流。 如果 $ErrorActionPreference 设置为将输出静音的状态,在查看错误时,此行为可能会导致 PowerShell 中的混淆,并且可能会丢失其他输出信息。

PowerShell 7.3 添加了一项新的实验性功能 PSNativeCommandErrorActionPreference,用于控制输出到 stderr 是否被视为错误。 有关详细信息,请参阅 $PSNativeCommandUseErrorActionPreference

运行 PowerShell 命令

如前所述,PowerShell 命令称为 cmdlet。 cmdlet 收集在 PowerShell 模块中,可按需加载。 可以使用任何编译的 .NET 语言或使用 PowerShell 脚本语言本身编写 Cmdlet。

运行其他命令的 PowerShell 命令

PowerShell 调用运算符&)允许运行存储在变量中并由字符串或脚本块表示的命令。 可以使用它运行任何本机命令或 PowerShell 命令。 如果需要动态构造本机命令的命令行参数,这在脚本中非常有用。 有关详细信息,请参阅调用运算符

Start-Process cmdlet 可用于运行本机命令,但仅在需要控制命令的执行方式时使用。 该 cmdlet 具有支持以下方案的参数:

  • 使用不同的凭据运行命令
  • 隐藏由新进程创建的控制台窗口
  • 重定向 stdin, stdout, 和 stderr
  • 使用不同的工作目录来执行命令

以下示例使用重定向的输入和输出流运行本机命令 sort.exe

$processOptions = @{
    FilePath = "sort.exe"
    RedirectStandardInput = "TestSort.txt"
    RedirectStandardOutput = "Sorted.txt"
    RedirectStandardError = "SortError.txt"
    UseNewEnvironment = $true
}
Start-Process @processOptions

有关详细信息,请参阅 Start-Process

在 Windows 上,Invoke-Item cmdlet 对指定项执行默认操作。 例如,它运行可执行文件,或使用与文档文件类型关联的应用程序打开文档文件。 默认操作具体取决于项类型,并由提供对项的访问权限的 PowerShell 提供程序解析。

以下示例在默认 Web 浏览器中打开 PowerShell 源代码存储库。

Invoke-Item https://github.com/PowerShell/PowerShell

有关详细信息,请参阅 Invoke-Item