选项卡在Powershell中使用start完成问题



我想在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-Processcmdlet (start是它的内置别名)的位置隐含的--FilePath参数填写一个值。

  • 由于-FilePath只接受文字(逐字)文件路径,不是也是通配符模式,制表符补全应该产生.[test].txt没有通配符模式元字符[]`转义。

相比之下,Invoke-Item(其内置别名为ii)通过其-Path参数支持通配符模式-以及通过其-LiteralPath参数文字(逐字)路径:

  • 由于-PathInvoke-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-ChildItemGet-Content(粗略地说,它们包含名称中包含ItemContentProperty的cmdlet)。


潜在的未来增强:

  • PowerShell的选项卡完成逻辑目前是硬连接到:

    • 默认为转义完成,
    • 除非目标参数名称(如果已知)恰好是-LiteralPath
  • GitHub issue #14149提议:

    • 默认为文字补全。
    • 除非目标参数(如果已知)通过SupportsWildcardsAttribute
    • 显式地表示支持通配符模式

何时使用Start-ProcessInvoke-Item:

  • 简单地说,Start-ProcessInvoke-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>
  • strong>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)都支持文字路径绑定,所以当你有一个确切的路径时,它总是最好/更安全的选择。

    最新更新