如何使自定义PowerShell模块覆盖路径中的程序?

ryevplcw  于 2022-12-29  发布在  Shell
关注(0)|答案(1)|浏览(197)

我有一个名为grep的自定义PowerShell 7模块,位于C:\Program Files\PowerShell\Modules\grep
在我的系统环境路径中,还有一个通过msys2安装的grep.exe
在终端调用grep时,调用的是路径中的grep.exe,但是我想从模块中调用grep,怎么做呢?

PS C:\> Get-Command grep

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Application     grep.exe                                           0.0.0.0    C:\msys64\usr\bin\grep.exe
PS C:\> Get-Module -ListAvailable | where Name -EQ grep

    Directory: C:\Program Files\PowerShell\Modules

ModuleType Version    PreRelease Name                                PSEdition ExportedCommands
---------- -------    ---------- ----                                --------- ----------------
Script     0.0                   grep                                Desk      grep
46qrfjad

46qrfjad1#

boxdog在注解中提供了关键的指针:

  • 给定PowerShell的command precedence,别名、cmdlet、函数,甚至Windows上的脚本(位于$env:PATH)[1]都优先于 * 外部程序 *(可执行文件)。
  • 因此,一旦您的模块被 * 导入 *,它的grep命令应该抢占grep.exe
  • 然而,PowerShell的自动加载机制 * 不会 * 触发包含给定名称命令的模块的导入,如果具有该名称的命令 * 已经可用 *,特别是以 * 外部程序 * 的形式。

换句话说:* * 要使grep模块的grep命令抢占grep.exe,必须确保已先导入模块**。
要作为单个命令的一部分隐式执行此操作,可以使用module-name * prefix * 执行以下操作:

# Use module prefix 'grep\' to explicitly target a command in it.
# This automatically triggers the module's import, if not already loaded.
grep\grep ...

如果您希望能够按原样使用grep来调用模块函数,则必须确保首先导入模块,这可以通过$PROFILE文件以两种方式之一实现(但请注意,可以通过PowerShell CLI-NoProfile绕过概要文件加载):

    • 无条件 * 在启动时导入模块:
  • 将以下内容放入$PROFILE文件中:
Import-Module grep
  • 在启动时定义一个 * alias *,它显式引用模块函数,如上所述,它只在会话中第一次调用别名时触发隐式导入:
  • 将以下内容放入$PROFILE文件中:
Set-Alias grep grep\grep

[1]在 * Windows * 上,除非调用 * 带有扩展名 * 的.exe文件,否则PowerShell会优先考虑具有给定(无扩展名)名称的.ps1文件。在 * Unix * 类平台上,可执行文件通常 * 没有 * 文件扩展名,后者优先。

相关问题