为什么在 PowerShell 中不能使用“查找”?

lit*_*lit 8 powershell find cmd.exe

find.exe在 PowerShell 控制台 shell 中使用这些参数时,有什么令人反感的地方?

这些命令在cmd.exeshell 中按预期工作:

PS C:\Windows\System32\WindowsPowerShell\v1.0> find /i "System.Diagnostics.Process" *.ps1xml
FIND: Parameter format not correct
PS C:\Windows\System32\WindowsPowerShell\v1.0> find /i "System.Diagnostics.Process" *.ps1xml
FIND: Parameter format not correct
PS C:\Windows\System32\WindowsPowerShell\v1.0> C:\Windows\System32\find.exe /i "System.Diagnostics.Process" *.ps1xml
FIND: Parameter format not correct
PS C:\Windows\System32\WindowsPowerShell\v1.0> C:\Windows\System32\find.exe /i "System.Diagnostics.Process" .\DotNetTypes.format.ps1xml
FIND: Parameter format not correct
Run Code Online (Sandbox Code Playgroud)

Pet*_*orf 8

尝试:

find /i "`"System.Diagnostics.Process`"" *.ps1xml
Run Code Online (Sandbox Code Playgroud)

我用Sysmon.exe的处决比较PowerShell.execmd.exe

对于 cmd.exe:

 Image: C:\Windows\System32\find.exe
 CommandLine: find  /i "System.Diagnostics.Process" *.ps1xml
 ParentImage: C:\Windows\System32\cmd.exe
Run Code Online (Sandbox Code Playgroud)

对于 PowerShell:

 Image: C:\Windows\System32\find.exe
 CommandLine: "C:\Windows\system32\find.exe" /i System.Diagnostics.Process *.ps1xml
 ParentImage: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Run Code Online (Sandbox Code Playgroud)

我们可以看到在 PowerShell 中,搜索项周围的引号丢失了,因此通过添加另一组双引号它应该可以工作。

  • 那是因为 [*您必须将字符串括在引号中*](https://technet.microsoft.com/en-us/library/bb490906.aspx) 在 `find` 中 (2认同)

phu*_*clv 5

特尔;博士:

转义双引号或将字符串放在单引号内

find.exe /i "`"System.Diagnostics.Process`"" *.ps1xml
find.exe /i """System.Diagnostics.Process""" *.ps1xml
find.exe /i '"System.Diagnostics.Process"' *.ps1xml
find.exe /i `"System.Diagnostics.Process`" *.ps1xml
Run Code Online (Sandbox Code Playgroud)

或使用逐字论证

find.exe --% "System.Diagnostics.Process" *.ps1xml
Run Code Online (Sandbox Code Playgroud)

正如 Peter Hahndorf 所说,PowerShell 正在剥离外部引号。请参阅PowerShell 从命令行参数中去除双引号。您可以通过在命令行中直接回显或写入字符串来检查它

PS C:\> echo C:\Windows\System32\find.exe /i "System.Diagnostics.Process" *.ps1xml
C:\Windows\System32\find.exe
/i
System.Diagnostics.Process
*.ps1xml
PS C:\> "System.Diagnostics.Process"
System.Diagnostics.Process
Run Code Online (Sandbox Code Playgroud)

恕我直言,这是一件好事,因为现在您可以使用单引号来包装字符串。您还有一种标准化的方法可以在类似于 bash 的参数中传递特殊字符,这与在 cmd嵌入双引号是一种痛苦的方式不同

根据PowerShell 引用规则,您必须通过`backticks`双引号或双引号本身来转义引号,或者像上面一样简单地将其放在单引号中

在像这样的简单情况下,当参数中没有空格时,您也可以直接转义双引号,而无需将其放在另一对引号中

find.exe /i `"System.Diagnostics.Process`" *.ps1xml
Run Code Online (Sandbox Code Playgroud)

但是,逐字参数有更简单的方法--%

在 PowerShell 3.0 中,特殊标记--%是向 PowerShell 发出信号以停止解释该行上的任何剩余字符。这可用于调用非 PowerShell 实用程序并完全按原样传递一些带引号的参数。

因此,您可以像这样使用它

find.exe --% "System.Diagnostics.Process" *.ps1xml
Run Code Online (Sandbox Code Playgroud)

或者,如果您不需要 Unicode 支持,那么您可以简单地find使用findstrwhich 不需要引号

PS C:\Users> help | findstr command
    topics at the command line.
    The Get-Help cmdlet displays help at the command line from content in
Run Code Online (Sandbox Code Playgroud)

但是如果 PowerShell 可用,那么您可以Select-String直接使用它的cmdlet。它比find和更强大findstr