我想在powershell中打开[test].txt
,但是当我按键盘上的tab键时,它会自动完成如下:
start '.`[test`].txt'
并产生如下错误:
start: Could not run this command due to error:系统找不到指定的文件。在行:1字符:1+ start '. ' [test '].txt'+ ~~~~~~~~~~~~~~~~~~~~~~~~+ CategoryInfo: InvalidOperation:(:) [Start-Process], InvalidOperationException+ fullqualifiederrid: InvalidOperationException, Microsoft.PowerShell.Commands.StartProcessCommand
我想在按tab键时删除反打勾字符。我该怎么做呢?
对Mathias R. Jessen的有益回答进行补充。
你看到的是PowerShell的选项卡完成中的限制。(至少到PowerShell Core 7.2.0-preview.9):
-
您正在为
Start-Process
cmdlet (start
是它的内置别名)的位置隐含的--FilePath
参数填写一个值。 -
由于
-FilePath
只接受文字(逐字)文件路径,不是也是通配符模式,制表符补全应该产生.[test].txt
,没有通配符模式元字符[
和]
的`
转义。
相比之下,Invoke-Item
(其内置别名为ii
)通过其-Path
参数支持通配符模式-以及通过其-LiteralPath
参数文字(逐字)路径:
-
由于
-Path
在Invoke-Item's
默认参数集中,并且是第一个位置参数,如果您使用Invoke-Item
而不是Start-Process
,选项卡完成值将按原来的方式工作。:# OK with tab-completion: positionally binds to -Path Invoke-Item '.`[test`].txt'
-
事实上,制表符补全知道手头的参数何时将绑定到
-LiteralPath
参数,然后不执行转义:# OK with tab-completion: due to explicitly targeting -LiteralPath, # no escaping is performed. Invoke-Item -LiteralPath .[test].txt
-
以上内容适用于所有提供程序cmdlet,例如
Get-ChildItem
和Get-Content
(粗略地说,它们包含名称中包含Item
、Content
或Property
的cmdlet)。
潜在的未来增强:
-
PowerShell的选项卡完成逻辑目前是硬连接到:
- 默认为转义完成,
- 除非目标参数名称(如果已知)恰好是
-LiteralPath
-
GitHub issue #14149提议:
- 默认为文字补全。
- 除非目标参数(如果已知)通过
SupportsWildcardsAttribute
显式地表示支持通配符模式
何时使用Start-Process
与Invoke-Item
:
-
简单地说,
Start-Process
是Invoke-Item
的超集;前者通常用于启动GUI可执行文件,而后者通常用于打开文档与注册的应用程序处理它们或目录文件资源管理器(在Windows上)。 -
虽然
Start-Process
可以做Invoke-Item
所能做的一切和更多,但的关键区别这相当于一个陷阱Start-Process
在$env:PATH
首先中列出的目录中查找仅通过名称标识的文件或目录而不是在当前目录中只有;在名称前加上.
(或使用完整路径)避免了这种歧义。
# Unambiguously targets .file.txt, i.e. a file in the *current* dir.
# In other words: The same as:
# Invoke-Item .file.txt
Invoke-Item file.txt
# AMBIGUOUS:
# !! *First* looks for a file.txt file in the directories
# !! listed in $env:PATH and opens the first one it finds.
# !! Only if none is found does it look in the current dir.
Start-Process file.txt
# OK - unambiguously looks in the current dir. only, thanks to "."
Start-Process .file.txt
注意:
自<<ul>Start-Process
通常用于启动可执行文件(GUI可执行文件;除了特殊情况,它是启动控制台应用程序的错误工具),在$env:PATH
中查找(首先)是有意义的,但是这种行为也扩展到文档(非-可执行文件)是意外的和有问题的-见GitHub问题#9469。有利的一面是Start-Process
(不像Invoke-Item
)可以打开url在默认的web浏览器中;例如:
Start-Process http://example.org
总之:
- 始终使用
Start-Process
代替Invoke-Item
是可以的,只要您通过在当前目录中的目标项加上.
前缀来避免歧义—幸运的是,当前目录中的项使用选项卡完成。
start
(Start-Process
的别名)真正设计用于启动可执行文件或外部命令。
要调用与任意文件关联的默认shell处理程序,请使用Invoke-Item
代替!
为了避免PowerShell试图将[...]
解释为通配符模式,请使用-LiteralPath
参数:
Invoke-Item -LiteralPath '.[test].txt'
所有的项目提供程序cmdlets (*-Item
,*-ChildItem
)都支持文字路径绑定,所以当你有一个确切的路径时,它总是最好/更安全的选择。