调用操作符“&”虽然简短,但是给我们执行Powershell命令提供了很大的方便。如果你之前将Powershell命令存储在了一个字符串中,或者一个变量中。此时,调用操作符就可以将字符串直接解释成命令并执行,如果在Powershell控制台中,你只须要输入即可。具体,如下:
#将命令存储在变量中: $command = "Dir" # 如果直接输出变量,字符串原样输出。 $command #Dir #如果使用调用操作符"&" & $command 目录: E: Mode LastWriteTime Length Name ---- ------------- ------ ---- d---- 2012/5/9 0:42 Blog d---- 2012/5/23 21:45 DooMLoRD_v3_ROOT-zergRush-busybox- su d---- 2012/6/1 20:21 Haitch-TFS d---- 2012/3/25 15:32 KillProcess
调用操作符只能接受单个命令
但是调用操作符不能接受全部的Powershell脚本或命令,只能接受单个的一条命令,例如使用:
$command = "Dir $env:windir" & $command 就会报错 无法将“Dir C:windows”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后重试。 所在位置 E:MyScript.ps1:6 字符: 2 + & <<<< $command + CategoryInfo : ObjectNotFound: (Dir C:windows:String) [], Comm andNotFoundException + FullyQualifiedErrorId : CommandNotFoundException
为什么会这样呢?追根溯源,Powershell中的调用符,首先会使用get-command去发现命令是否可用,而get-command的确只支持单独的一条命令,不支持命令串或者脚本串。 调用操作符执行CommandInfo对象 调用操作符初始化时会将指定的文本传递给get-command,然后有get-command去检索命令,事实上,调用操作符甚至可以直接执行一个CommandInfo对象,绕过自身的内部get-command,例如:
PS E:> $command=Get-Command tasklist PS E:> $command CommandType Name ----------- ---- Application tasklist.exe PS E:> & $command 映像名称 PID 会话名 会话# 内存使用 ========================= ======== ================ =========== ============ System Idle Process 0 Services 0 24 K System 4 Services 0 560 K smss.exe 356 Services 0 756 K csrss.exe 564 Services 0 3,744 K csrss.exe 680 Console 1 71,512 K wininit.exe 688 Services 0 2,904 K services.exe 740 Services 0 8,552 K lsass.exe 764 Services 0 10,676 K lsm.exe 776 Services 0 3,240 K
通过命令名称唯一标识一条命令
但是可能存在别名,命令,函数的的名称一样,那Powershell会不会纠结到底执行哪个呢?当然不会,因为它们之间是有一个优先级的。从高到底,依次为:
Alias(1)
Function(2)
Filter(2)
Cmdlet(3)
Application(4)
ExternalScript(5)
Script (-)
下面举个例子:
PS E:> function Ping(){"我是Ping函数"} PS E:> Set-Alias -Name Ping -Value echo CommandType Name Definition ----------- ---- ---------- Alias Ping echo Function Ping param()... Application PING.EXE C:windowsSYSTEM32PING.EXE PS E:> ping "测试我的Ping,估计执行的别名echo" 测试我的Ping,估计执行的别名echo PS E:> del Alias:Ping PS E:> ping ; #别名已经被删除,估计执行的是函数PING 我是Ping函数 PS E:> del Function:Ping PS E:> ping baidu.com ; #函数已经被删除,估计执行的是函数ping 程序 正在 Ping baidu.com [220.181.111.85] 具有 32 字节的数据: 请求超时。 请求超时。 请求超时。 请求超时。 220.181.111.85 的 Ping 统计信息: 数据包: 已发送 = 4,已接收 = 0,丢失 = 4 (100% 丢失),
那怎样突破优先级的限制执行指定的命令呢?方法都是大同小异,通过特定信息过滤到指定的CommandInfo对象,然后直接使用我们本篇的调用操作符。例如当存在如下的命令Ping命令
CommandType Name ----------- ---- Alias Ping Function Ping Application PING.EXE 我想调用第三个,可以使用: PS E:> $command=Get-Command -Name ping | where {$_.CommandType -eq "Application" } PS E:> & $command 用法: ping [-t] [-a] [-n count] [-l size] [-f] [-i TTL] [-v TOS] [-r count] [-s count] [[-j host-list] | [-k host-list]] [-w timeout] [-R] [-S srcaddr] [-4] [-6] target_name 选项: -t Ping 指定的主机,直到停止。 若要查看统计信息并继续操作 - 请键入 Control-Break; 若要停止 - 请键入 Control-C。 -a 将地址解析成主机名。 -n count 要发送的回显请求数。 -l size 发送缓冲区大小。 -f 在数据包中设置“不分段”标志(仅适用于 IPv4)。 -i TTL 生存时间。 -v TOS 服务类型(仅适用于 IPv4。该设置已不赞成使用,且 对 IP 标头中的服务字段类型没有任何影响)。 -r count 记录计数跃点的路由(仅适用于 IPv4)。 -s count 计数跃点的时间戳(仅适用于 IPv4)。 -j host-list 与主机列表一起的松散源路由(仅适用于 IPv4)。 -k host-list 与主机列表一起的严格源路由(仅适用于 IPv4)。 -w timeout 等待每次回复的超时时间(毫秒)。 -R 同样使用路由标头测试反向路由(仅适用于 IPv6)。 -S srcaddr 要使用的源地址。 -4 强制使用 IPv4。 -6 强制使用 IPv6。 #或者& (Get-Command -Name ping)[2]
本文链接: https://www.pstips.net/powershell-call-operator.html
请尊重原作者和编辑的辛勤劳动,欢迎转载,并注明出处!
请尊重原作者和编辑的辛勤劳动,欢迎转载,并注明出处!
博主你好,
使用: $command=Get-Command -Name ping | where {$_.CommandType -eq “Application” } 语句得到的 $command 为null,
而使用 $command = Get-Command -Name ping -CommandType Application 可以得到对象.
我的是3.0,不知道是不是版本问题?
可能原书比较老。
get-command在新版里缺省只返回最高优先级的命令,文中例子在5.0的ps里要加上-all选项,或者用-CommandType Application指定类型。
get-command在ps5.0里缺省只返回最高优先级的命令,文中例子在5.0的ps里要加上-all选项。
$command = “Dir $env:windir”
& $command
这句在新版PS(5.0)里报错,如果去掉dir后面的参数以及空格就可以运行正常。
第一个命令框里的内容容易引起歧义……
$command = “dir $env:windir”
& $command执行会出错
$command = “dir”
& $command执行正确
确实是,第一个例 子中写错了,应该是 $Command=”dir”, 这样下面的展示内容才对得上。
现在的版本V5上,& {dir $env:windir} 可以运行,但是 $c=”{dir $env:windir}”
& $c 却不能运行。
单纯的这样写{dir C:\Windows},PowerShell解释器会认为它是语句块,可以用& 来执行。
& 后面的跟的参数,必须是一个cmdlet,函数名,脚本文件,或者语句块,或者可运行程序。
无法将“{dir C:\Windows}”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。
感谢反馈,已更新
楼主,请教下如果把执行下面的命令,我想把一个字符串$PktCapCmd当做指令来执行?
$PktCapCmd=”${PktCapExe} -tests sp1bench -sp1bench Testcaseid=$TcNum”