msys2 等でインストールしたり where.exe を使う方法もありますが、PowerShell だけでできる方法にします。
こちらの記事を参考にしました。
ファイルのパスを取得する方法
Get-Command
で返ってくる Definition
あるいは Source
プロパティにファイルのパスが含まれています。
ですが、 Source
プロパティよりも Definition
プロパティの方が汎用性が高いので、こちらを使います。
Get-member
をしてみると、
PS> gcm pwsh | gm
TypeName: System.Management.Automation.ApplicationInfo
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ResolveParameter Method System.Management.Automation.ParameterMetadata ResolveParameter(string name)
ToString Method string ToString()
CommandType Property System.Management.Automation.CommandTypes CommandType {get;}
Definition Property string Definition {get;}
Extension Property string Extension {get;}
Module Property psmoduleinfo Module {get;}
ModuleName Property string ModuleName {get;}
Name Property string Name {get;}
OutputType Property System.Collections.ObjectModel.ReadOnlyCollection[System.Management.Automation.PST... Parameters Property System.Collections.Generic.Dictionary[string,System.Management.Automation.Paramete... ParameterSets Property System.Collections.ObjectModel.ReadOnlyCollection[System.Management.Automation.Com... Path Property string Path {get;}
RemotingCapability Property System.Management.Automation.RemotingCapability RemotingCapability {get;}
Source Property string Source {get;}
Version Property version Version {get;}
Visibility Property System.Management.Automation.SessionStateEntryVisibility Visibility {get;set;}
FileVersionInfo ScriptProperty System.Object FileVersionInfo {get=[System.Diagnostics.FileVersionInfo]::getversio... HelpUri ScriptProperty System.Object HelpUri {get=$oldProgressPreference = $ProgressPreference...
これだけのものが出てきますが、欲しい情報は Definition
だけです。
それだけを取り出す方法はいくつかあり、上の記事で紹介されている (gcm $command).Definition
以外にも
PS > (gcm pwsh).Definition
C:\Program Files\PowerShell\6.0.0\pwsh.exe
PS> gcm pwsh | fl -p Definition
Definition : C:\Program Files\PowerShell\6.0.0\pwsh.exe
PS> gcm pwsh | select -p Definition
Definition
----------
C:\Program Files\PowerShell\6.0.0\pwsh.exe
などがあります。
それぞれ表示が違うので好みで使い分けてください。
上の記事で紹介されていた Format-List
もオプションで -Property Definition
と指定すれば Definition
だけを取り出せます。
コマンドとして使える様にする
意味合い的には Select-Object -Property Definition
が一番妥当だと思うのですが、 Select-Object
では表示されず Format-List
では表示されるものもあるので、 Format-List
を使ってコマンド化します。
といっても簡単で、
function which ($command) {
Get-command -Name $command -ShowCommandInfo | Format-List -Property Definition
}
これで完了です。
これを毎回使える様にするために、このファンクションを $PROFILE
に書きましょう。
$PROFILE
には4種類あり、
PS> $PROFILE | gm -m NoteProperty | select -p Name, MemberType
Name MemberType
---- ----------
AllUsersAllHosts NoteProperty
AllUsersCurrentHost NoteProperty
CurrentUserAllHosts NoteProperty
CurrentUserCurrentHost NoteProperty
AllUsers
か CurrentUser
かはその名の通り、 AllHosts
か CurrentHost
かはちゃんと分かっていませんが、
PowerShell で CurrentHost
に設定した場合 PowerShell ISE
には適用されません。
個人で使っている範囲で、PowerShell にも ISE にも適用して欲しいのであれば、 CurrentUserAllHosts
に書くのが良いでしょう。
# ディレクトリやファイルが無い場合、ファイルを作成
PS> $profilePath = Split-Path -Path $PROFILE.CurrentUserAllHosts -Parent
PS> $profileName = Split-Path -Path $PROFILE.CurrentUserAllHosts -Leaf
PS> mkdir $profilePath
PS> ni -Path $profilePath -Name $profileName
# 既定のエディタで開く
PS> ii $PROFILE.CurrentUserAllHosts
# ファンクションを書いて保存したら読み込む
PS> . $PROFILE.CurrentUserAllHosts
これで PowerShell で which
コマンドのようなものが使える様になりました。
おまけ
-
上で
Source
プロパティよりもDefinition
プロパティの方が汎用性が高いと言ったのは pwsh(.exe) のようにファイルのものではどちらでも変わりませんが、例えばファンクションやエイリアス、コマンドレットでは
PS > gcm which | fl -Property Source Source : PS > gcm gcm | fl -Property Source Source : PS > gcm which | fl -Property Definition Definition : param($command) Get-Command -Name $command -ShowCommandInfo | Format-List -Property Definition PS > gcm gcm | fl -Property Definition Definition : Get-Command PS > gcm Get-Command | fl -Property Definition Definition : Get-Command [[-ArgumentList] <Object[]>] [-Verb <string[]>] [-Noun <string[]>] [-Module <string[]>] [-FullyQualifiedModule <ModuleSpecification[]>] [-TotalCount <int>] [-Syntax] [-ShowCommandInfo] [-All] [-ListImported] [-ParameterName <string[]>] [-ParameterType <PSTypeName[]>] [<CommonParameters>] Get-Command [[-Name] <string[]>] [[-ArgumentList] <Object[]>] [-Module <string[]>] [-FullyQualifiedModule<ModuleSpecification[]>] [-CommandType <CommandTypes>] [-TotalCount <int>] [-Syntax] [-ShowCommandInfo] [-All] [-ListImported] [-ParameterName <string[]>] [-ParameterType <PSTypeName[]>] [<CommonParameters>]
と違いが出ます。
このように
which
コマンドを定義しておけば、ファイルのパスを見つけたい時だけではなく、ファンクションの定義を確認したいとき例えばwhich mkdir
やコマンドレットのオプションを確認したいときGet-Help Get-Command
の代わりにwhich Get-Command
と使える様になります。 -
上で
Select-Object
では表示されずFormat-List
では表示されるものもあると書いた事について
これも1つめと同じでファンクションやコマンドレットで差が出ます。
Definition
の出力が複数行にわたる場合や長い場合Select-Object
では省略されます。PS > gcm which | select -p Definition Definition ---------- param($command)... PS> gcm Get-Command | select -p Definition Definition ---------- ...