[玩转系统] 关于解析
作者:精品下载站 日期:2024-12-14 02:20:50 浏览:14 分类:玩电脑
关于解析
简短描述
描述 PowerShell 如何解析命令。
详细描述
当您在命令提示符处输入命令时,PowerShell 将命令文本分解为一系列称为“令牌”的段,然后确定如何解释每个令牌。
例如,如果您输入:
Write-Host book
PowerShell 将命令分解为两个标记:Write-Host
和 book
,并使用两种主要解析模式之一独立解释每个标记:表达式模式和参数模式。
笔记
当 PowerShell 解析命令输入时,它会尝试将命令名称解析为 cmdlet 或本机可执行文件。如果命令名称不完全匹配,PowerShell 会在命令前面添加 Get-
作为默认动词。例如,PowerShell 将 Service
解析为 Get-Service
。不建议使用该功能,原因如下:
- 这是低效的。这会导致 PowerShell 进行多次搜索。
- 首先解析具有相同名称的外部程序,因此您可能无法执行预期的 cmdlet。
Get-Help
和Get-Command
无法识别无动词名称。- 命令名称可以是保留字或语言关键字。
Process
两者兼而有之,并且无法解析为Get-Process
。
表达方式
表达式模式用于组合表达式,这是脚本语言中值操作所需的。表达式是 PowerShell 语法中值的表示形式,可以是简单的也可以是复合的,例如:
文字表达式是其值的直接表示:
'hello'
32
变量表达式携带它们引用的变量的值:
$x
$script:path
运算符组合其他表达式进行求值:
-12
-not $Quiet
3 + 7
$input.Length -gt 1
- 字符串文字必须包含在引号中。
- 数字被视为数值而不是一系列字符(除非转义)。
- 运算符,包括
-
和-not
等一元运算符以及+
和-gt
等二元运算符 被解释为运算符并对其参数(操作数)应用各自的运算。 - 属性和转换表达式被解析为表达式并应用于从属表达式。例如:
[int] '7'
。 - 变量引用将被评估为其值,但splatting被禁止并导致解析器错误。
- 其他任何内容都被视为要调用的命令。
论证模式
解析时,PowerShell 首先将输入解释为表达式。但是,当遇到命令调用时,解析会以参数模式继续。如果您的参数包含空格(例如路径),则必须将这些参数值括在引号中。
参数模式旨在解析 shell 环境中命令的参数和参数。所有输入都被视为可扩展字符串,除非它使用以下语法之一:
美元符号 (
$
) 后跟变量名称开始变量引用,否则它将被解释为可扩展字符串的一部分。变量引用可以包括成员访问或索引。- 简单变量引用后面的附加字符(例如
$HOME
)被视为同一参数的一部分。将变量名称括在大括号 ({}
) 中,以将其与后续字符分隔开。例如,$ {HOME}
。
- 简单变量引用后面的附加字符(例如
- 当变量引用包含成员访问时,任何附加字符中的第一个字符将被视为新参数的开始。例如,
$HOME.Length-more
会产生两个参数:$HOME.Length
的值和字符串文字-more
。
引号('
和 "
)开始字符串
大括号 ({}
) 开始新的脚本块
逗号 (,
) 引入作为数组传递的列表,除非被调用的命令是本机应用程序,在这种情况下它们将被解释为可扩展字符串的一部分。不支持开头、连续或结尾逗号。
括号 (()
) 开始一个新表达式
子表达式运算符 ($()
) 开始嵌入表达式
初始 at 符号 (@
) 开始表达式语法,例如 splatting (@args
)、数组 (@(1,2,3)
)、和哈希表文字 (@{a=1;b=2}
)。
标记开头的 ()
、$()
和 @()
创建一个新的解析上下文,其中可以包含表达式或嵌套命令。
- 当后跟附加字符时,第一个附加字符被视为新的单独参数的开始。
$()
时,其工作方式类似于可扩展字符串,()
启动一个作为表达式的新参数,而 @()
被视为文字 @
,其中 ()
开始一个新的表达式参数。除了仍然需要转义的元字符之外,其他所有内容都被视为可扩展字符串。请参阅处理特殊字符。
- 参数模式元字符(具有特殊语法意义的字符)为:
<space> ' " ` , ; ( ) { } | & @ #
。其中,< > @ #
仅在标记的开头是特殊的。
停止解析标记 (--%
) 更改所有剩余参数的解释。有关更多信息,请参阅下面的停止解析标记部分。
示例
下表提供了在表达式模式和参数模式下处理的标记的几个示例以及这些标记的评估。对于这些示例,变量 $a
的值为 4
。
2
Expression
2 (integer)
`2
Expression
"2" (command)
Write-Output 2
Expression
2 (integer)
2+2
Expression
4 (integer)
Write-Output 2+2
Argument
"2+2" (string)
Write-Output(2+2)
Expression
4 (integer)
$a
Expression
4 (integer)
Write-Output $a
Expression
4 (integer)
$a+2
Expression
6 (integer)
Write-Output $a+2
Argument
"4+2" (string)
$-
Argument
"$-" (command)
Write-Output $-
Argument
"$-" (string)
a$a
Expression
"a$a" (command)
Write-Output a$a
Argument
"a4" (string)
a'$a'
Expression
"a$a" (command)
Write-Output a'$a'
Argument
"a$a" (string)
a"$a"
Expression
"a$a" (command)
Write-Output a"$a"
Argument
"a4" (string)
a$(2)
Expression
"a$(2)" (command)
Write-Output a$(2)
Argument
"a2" (string)
每个标记都可以解释为某种对象类型,例如布尔或字符串。 PowerShell 尝试根据表达式确定对象类型。对象类型取决于命令期望的参数类型以及 PowerShell 是否知道如何将参数转换为正确的类型。下表显示了分配给表达式返回值的类型的几个示例。
Write-Output !1
argument
"!1" (string)
Write-Output (!1)
expression
False (Boolean)
Write-Output (2)
expression
2 (integer)
Set-Variable AB A,B
argument
'A','B' (array)
CMD /CECHO A,B
argument
'A,B' (string)
CMD /CECHO $AB
expression
'A B' (array)
CMD /CECHO :$AB
argument
':A B' (string)
处理特殊字符
反引号字符 (`
) 可用于转义表达式中的任何特殊字符。这对于转义要用作文字字符而不是元字符的参数模式元字符最有用。例如,要使用美元符号 ($
) 作为可扩展字符串中的文字:
"The value of `$ErrorActionPreference is '$ErrorActionPreference'."
The value of $ErrorActionPreference is 'Continue'.
线路延续
反引号字符也可以用在行尾,以便您在下一行继续输入。这提高了采用多个具有长名称和参数值的参数的命令的可读性。例如:
New-AzVm `
-ResourceGroupName "myResourceGroupVM" `
-Name "myVM" `
-Location "EastUS" `
-VirtualNetworkName "myVnet" `
-SubnetName "mySubnet" `
-SecurityGroupName "myNetworkSecurityGroup" `
-PublicIpAddressName "myPublicIpAddress" `
-Credential $cred
但是,您应该避免使用续行。
- 反引号字符可能很难看到并且很容易忘记。
- 反引号后的额外空格会中断行的延续。由于空间很难看到,因此很难发现错误。
PowerShell 提供了多种在语法中的自然点换行的方法。
- 在管道字符 (
|
) 之后 - 在二元运算符之后(
+
、-
、-eq
等) - 数组中逗号 (
,
) 之后 - 打开
[
、{
、(
等字符后
对于较大的参数集,请使用splatting。例如:
$parameters = @{
ResourceGroupName = "myResourceGroupVM"
Name = "myVM"
Location = "EastUS"
VirtualNetworkName = "myVnet"
SubnetName = "mySubnet"
SecurityGroupName = "myNetworkSecurityGroup"
PublicIpAddressName = "myPublicIpAddress"
Credential = $cred
}
New-AzVm @parameters
将参数传递给本机命令
从 PowerShell 运行本机命令时,参数首先由 PowerShell 解析。然后将解析后的参数连接成单个字符串,每个参数用空格分隔。
例如,以下命令调用 icacls.exe 程序。
icacls X:\VMS /grant Dom\HVAdmin:(CI)(OI)F
要在 PowerShell 2.0 中运行此命令,必须使用转义字符以防止 PowerShell 误解括号。
icacls X:\VMS /grant Dom\HVAdmin:`(CI`)`(OI`)F
停止解析标记
从 PowerShell 3.0 开始,您可以使用 stop-parsing (--%
) 令牌来阻止 PowerShell 将输入解释为 PowerShell 命令或表达式。
笔记
停止解析令牌仅适用于在 Windows 平台上使用本机命令。
调用本机命令时,请将停止解析标记放在程序参数之前。这种技术比使用转义字符更容易防止误解。
当遇到停止解析标记时,PowerShell 会将行中的剩余字符视为文字。它执行的唯一解释是替换使用标准 Windows 表示法的环境变量的值,例如 %USERPROFILE%
。
icacls X:\VMS --% /grant Dom\HVAdmin:(CI)(OI)F
PowerShell 将以下命令字符串发送到 icacls.exe 程序:
X:\VMS /grant Dom\HVAdmin:(CI)(OI)F
停止解析标记仅在下一个换行符或管道字符之前有效。您不能使用行继续符 (`
) 来扩展其效果,也不能使用命令分隔符 (;
) 来终止其效果。
除了 %variable%
环境变量引用之外,您不能在命令中嵌入任何其他动态元素。不支持将 %
字符转义为 %%
(您可以在批处理文件中执行此操作)。 %%
标记总是被扩展。如果 <name>
未引用已定义的环境变量,则令牌将按原样传递。
您不能使用流重定向(如 >file.txt
),因为它们作为参数逐字传递给目标命令。
在以下示例中,第一步运行命令而不使用停止解析标记。 PowerShell 计算带引号的字符串并将值(不带引号)传递给 cmd.exe
,这会导致错误。
PS> cmd /c echo "a|b"
'b' is not recognized as an internal or external command,
operable program or batch file.
PS> cmd /c --% echo "a|b"
"a|b"
笔记
使用 PowerShell cmdlet 时不需要停止解析令牌。但是,将参数传递给 PowerShell 函数可能很有用,该函数旨在使用这些参数调用本机命令。
传递包含引号字符的参数
某些本机命令需要包含引号字符的参数。 PowerShell 7.3 更改了解析命令行以获取本机命令的方式。
警告
新行为是对 Windows PowerShell 5.1 行为的重大更改。这可能会破坏调用本机应用程序时解决各种问题的脚本和自动化。使用停止解析标记 (--%
) 或 Start-Process
cmdlet 以避免在需要时传递本机参数。
新的 $PSNativeCommandArgumentPassing
首选项变量控制此行为。该变量允许您选择运行时的行为。有效值为 Legacy
、Standard
和 Windows
。默认行为是特定于平台的。在 Windows 平台上,默认设置为 Windows
,非 Windows 平台默认为 Standard
。
Legacy
是历史行为。 Windows
和 Standard
模式的行为相同,只是在 Windows
模式下,以下文件的调用会自动使用 Legacy
风格参数传递。
cmd.exe
cscript.exe
wscript.exe
.bat
结尾.cmd
结尾.js
结尾.vbs
结尾.wsf
结尾如果 $PSNativeCommandArgumentPassing
设置为 Legacy
或 Standard
,则解析器不会检查这些文件。
笔记
以下示例使用 TestExe.exe
工具。您可以从源代码构建TestExe
。请参阅 PowerShell 源存储库中的 TestExe。
此更改带来的新行为:
带有嵌入引号的文字或可扩展字符串现在保留引号:
PS> $a = 'a" "b' PS> TestExe -echoargs $a 'c" "d' e" "f Arg 0 is <a" "b> Arg 1 is <c" "d> Arg 2 is <e f>
现在保留作为参数的空字符串:
PS> TestExe -echoargs '' a b '' Arg 0 is <> Arg 1 is <a> Arg 2 is <b> Arg 3 is <>
这些示例的目标是将目录路径(带有空格和引号)"C:\Program Files (x86)\Microsoft\"
传递给本机命令,以便它接收作为带引号的路径细绳。
在 Windows
或 Standard
模式下,以下示例产生预期结果:
TestExe -echoargs """${env:ProgramFiles(x86)}\Microsoft\"""
TestExe -echoargs '"C:\Program Files (x86)\Microsoft\"'
要在 Legacy
模式下获得相同的结果,您必须转义引号或使用停止解析标记 (--%
):
TestExe -echoargs """""${env:ProgramFiles(x86)}\Microsoft\"""""
TestExe -echoargs "\""C:\Program Files (x86)\Microsoft\"""
TestExe -echoargs --% ""\""C:\Program Files (x86)\Microsoft\"\"""
TestExe -echoargs --% """C:\Program Files (x86)\Microsoft\""
TestExe -echoargs --% """%ProgramFiles(x86)%\Microsoft\""
笔记
PowerShell 不会将反斜杠 (\
) 字符识别为转义字符。它是 ProcessStartInfo.ArgumentList 的底层 API 使用的转义字符。
PowerShell 7.3 还添加了跟踪本机命令参数绑定的功能。有关详细信息,请参阅跟踪命令。
将参数传递给 PowerShell 命令
从 PowerShell 3.0 开始,您可以使用参数结束标记 (--
) 来阻止 PowerShell 将输入解释为 PowerShell 参数。这是 POSIX Shell 和实用程序规范中指定的约定。
参数结束标记
参数结束标记 (--
) 指示其后面的所有参数都将以实际形式传递,就像在它们周围放置双引号一样。例如,使用 --
您可以输出字符串 -InputObject
而不使用引号或将其解释为参数:
Write-Output -- -InputObject
-InputObject
与停止解析 (--%
) 标记不同,--
标记后面的任何值都可以被 PowerShell 解释为表达式。
Write-Output -- -InputObject $env:PROCESSOR_ARCHITECTURE
-InputObject
AMD64
此行为仅适用于 PowerShell 命令。如果在调用外部命令时使用 --
标记,则 --
字符串将作为参数传递给该命令。
TestExe -echoargs -a -b -- -c
输出显示 --
作为参数传递给 TestExe
。
Arg 0 is <-a>
Arg 1 is <-b>
Arg 2 is <-->
Arg 3 is <-c>
波形符 (~)
波形符 (~
) 在 PowerShell 中具有特殊含义。当它在路径开头与 PowerShell 命令一起使用时,波浪号字符将扩展到用户的主目录。如果波浪号字符在路径中的其他任何位置使用,它将被视为文字字符。
PS D:\temp> $PWD
Path
----
D:\temp
PS D:\temp> Set-Location ~
PS C:\Users\user2> $PWD
Path
----
C:\Users\user2
在此示例中,New-Item
的 Name 参数需要一个字符串。波形符字符被视为文字字符。要更改到新创建的目录,您必须使用波浪号字符限定路径。
PS D:\temp> Set-Location ~
PS C:\Users\user2> New-Item -Type Directory -Name ~
Directory: C:\Users\user2
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 5/6/2024 2:08 PM ~
PS C:\Users\user2> Set-Location ~
PS C:\Users\user2> Set-Location .\~
PS C:\Users\user2\~> $PWD
Path
----
C:\Users\user2\~
当您在本机命令中使用波浪号字符时,PowerShell 会将波浪号作为文字字符传递。在路径中使用波浪号会导致 Windows 上不支持波浪号字符的本机命令出现错误。
PS D:\temp> $PWD
Path
----
D:\temp
PS D:\temp> Get-Item ~\repocache.clixml
Directory: C:\Users\user2
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 4/29/2024 3:42 PM 88177 repocache.clixml
PS D:\temp> more.com ~\repocache.clixml
Cannot access file D:\temp\~\repocache.clixml
参见
- about_Command_Syntax
猜你还喜欢
- 03-30 [玩转系统] 如何用批处理实现关机,注销,重启和锁定计算机
- 02-14 [系统故障] Win10下报错:该文件没有与之关联的应用来执行该操作
- 01-07 [系统问题] Win10--解决锁屏后会断网的问题
- 01-02 [系统技巧] Windows系统如何关闭防火墙保姆式教程,超详细
- 12-15 [玩转系统] 如何在 Windows 10 和 11 上允许多个 RDP 会话
- 12-15 [玩转系统] 查找 Exchange/Microsoft 365 中不活动(未使用)的通讯组列表
- 12-15 [玩转系统] 如何在 Windows 上安装远程服务器管理工具 (RSAT)
- 12-15 [玩转系统] 如何在 Windows 上重置组策略设置
- 12-15 [玩转系统] 如何获取计算机上的本地管理员列表?
- 12-15 [玩转系统] 在 Visual Studio Code 中连接到 MS SQL Server 数据库
- 12-15 [玩转系统] 如何降级 Windows Server 版本或许可证
- 12-15 [玩转系统] 如何允许非管理员用户在 Windows 中启动/停止服务
取消回复欢迎 你 发表评论:
- 精品推荐!
-
- 最新文章
- 热门文章
- 热评文章
[影视] 黑道中人 Alto Knights(2025)剧情 犯罪 历史 电影
[古装剧] [七侠五义][全75集][WEB-MP4/76G][国语无字][1080P][焦恩俊经典]
[实用软件] 虚拟手机号 电话 验证码 注册
[电视剧] 安眠书店/你 第五季 You Season 5 (2025) 【全10集】
[电视剧] 棋士(2025) 4K 1080P【全22集】悬疑 犯罪 王宝强 陈明昊
[软件合集] 25年6月5日 精选软件22个
[软件合集] 25年6月4日 精选软件36个
[短剧] 2025年06月04日 精选+付费短剧推荐33部
[短剧] 2025年06月03日 精选+付费短剧推荐25部
[软件合集] 25年6月3日 精选软件44个
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电视剧] 欢乐颂.5部全 (2016-2024)
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[影视] 【稀有资源】香港老片 艺坛照妖镜之96应召名册 (1996)
[剧集] 神经风云(2023)(完结).4K
[剧集] [BT] [TVB] [黑夜彩虹(2003)] [全21集] [粤语中字] [TV-RMVB]
[实用软件] 虚拟手机号 电话 验证码 注册
[资源] B站充电视频合集,包含多位重量级up主,全是大佬真金白银买来的~【99GB】
[影视] 内地绝版高清录像带 [mpg]
[书籍] 古今奇书禁书三教九流资料大合集 猎奇必备珍藏资源PDF版 1.14G
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电影] 美国队长4 4K原盘REMUX 杜比视界 内封简繁英双语字幕 49G
[电影] 死神来了(1-6)大合集!
[软件合集] 25年05月13日 精选软件16个
[精品软件] 25年05月15日 精选软件18个
[绝版资源] 南与北 第1-2季 合集 North and South (1985) /美国/豆瓣: 8.8[1080P][中文字幕]
[软件] 25年05月14日 精选软件57个
[短剧] 2025年05月14日 精选+付费短剧推荐39部
[短剧] 2025年05月15日 精选+付费短剧推荐36部
- 最新评论
-
- 热门tag