I have a custom PowerShell 7 Module called grep
located at C:\Program Files\PowerShell\Modules\grep
.
In my system environment path, there is also a grep.exe
installed through msys2.
When calling grep
in the terminal, grep.exe
from the path is invoked. However, I want to call the grep
from the module. How can I do that?
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
CodePudding user response:
boxdog has provided the crucial pointers in a comment:
Given PowerShell's command precedence, aliases, cmdlets, functions and, on Windows, even scripts (located in
$env:PATH
)[1] take precedence over external programs (executables).Therefore, once your module has been imported, it's
grep
command should preemptgrep.exe
.However, PowerShell's auto-loading mechanism does not trigger import of modules containing a command with a given name, if a command with that name is already available, notably in the form of an external program.
In other words: For your grep
module's grep
command to preempt grep.exe
, you must ensure that your module has been imported first.
To do that implicitly, as part of a single command, you can do the following, using a 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 ...
If you want to be able to use grep
as-is to invoke your module function, you must ensure that your module is imported first, which you can achieve in one of two ways, via your $PROFILE
file (but note that profile loading can be bypassed via the PowerShell CLI with -NoProfile
):
Unconditionally import your module on startup:
Place the following in your
$PROFILE
file:Import-Module grep
Define an alias on startup, which explicitly references the module function, as above, which triggers implicit importing:
Place the following in your
$PROFILE
file:Set-Alias grep grep\grep
[1] On Windows, unless an .exe
file is invoked with its extension, PowerShell gives precedence to .ps1
files with a given (extension-less) name. On Unix-like platforms, where executables usually do not have filename extensions, the latter take precedence.