Bagaimana cara saya bertanya pada PowerShell di mana ada sesuatu?
Misalnya, "notepad mana" dan mengembalikan direktori tempat notepad.exe dijalankan sesuai dengan jalur saat ini.
Bagaimana cara saya bertanya pada PowerShell di mana ada sesuatu?
Misalnya, "notepad mana" dan mengembalikan direktori tempat notepad.exe dijalankan sesuai dengan jalur saat ini.
Jawaban:
Alias pertama yang saya buat setelah saya mulai menyesuaikan profil saya di PowerShell adalah 'yang'.
New-Alias which get-command
Untuk menambahkan ini ke profil Anda, ketikkan ini:
"`nNew-Alias which get-command" | add-content $profile
`N pada awal baris terakhir adalah untuk memastikannya akan dimulai sebagai baris baru.
Get-Command <command> | Format-Table Path, Name
jadi saya bisa mendapatkan jalan tempat perintah duduk juga.
select -expandproperty Path
.
(gcm <command>).definition
untuk mendapatkan jalur saja. gcm
adalah alias default untuk Get-Command
. Anda juga dapat menggunakan wildcard, misalnya: (gcm win*.exe).definition
.
Berikut ini adalah setara * nix aktual, yaitu memberikan * nix-style output.
Get-Command <your command> | Select-Object -ExpandProperty Definition
Ganti saja dengan apa pun yang Anda cari.
PS C:\> Get-Command notepad.exe | Select-Object -ExpandProperty Definition
C:\Windows\system32\notepad.exe
Ketika Anda menambahkannya ke profil Anda, Anda akan ingin menggunakan fungsi daripada alias karena Anda tidak dapat menggunakan alias dengan pipa:
function which($name)
{
Get-Command $name | Select-Object -ExpandProperty Definition
}
Sekarang, ketika Anda memuat ulang profil Anda, Anda dapat melakukan ini:
PS C:\> which notepad
C:\Windows\system32\notepad.exe
okta
yang menunjuk ke skrip Powershell bernama okta.ps1
yang tidak ada di saya $PATH
. Menggunakan jawaban yang diterima mengembalikan nama skrip ( okta -> okta.ps1
). Ini baik-baik saja tetapi tidak memberi tahu saya lokasi okta.ps1
. Namun, menggunakan jawaban ini memberi saya seluruh jalur ( C:\Users\blah\etc\scripts\okta.ps1
). Jadi +1 dari saya.
Saya biasanya cukup mengetik:
gcm notepad
atau
gcm note*
gcm adalah alias default untuk Get-Command.
Pada sistem saya, gcm note * output:
[27] » gcm note*
CommandType Name Definition
----------- ---- ----------
Application notepad.exe C:\WINDOWS\notepad.exe
Application notepad.exe C:\WINDOWS\system32\notepad.exe
Application Notepad2.exe C:\Utils\Notepad2.exe
Application Notepad2.ini C:\Utils\Notepad2.ini
Anda mendapatkan direktori dan perintah yang cocok dengan apa yang Anda cari.
gcm note* | select CommandType, Name, Definition
. Jika Anda sering menjalankannya, Anda mungkin harus membungkusnya dalam suatu fungsi.
Coba contoh ini:
(Get-Command notepad.exe).Path
(gcm py.exe).path
Proposisi saya untuk fungsi Mana:
function which($cmd) { get-command $cmd | % { $_.Path } }
PS C:\> which devcon
C:\local\code\bin\devcon.exe
Pertandingan cepat dan kotor untuk Unix which
adalah
New-Alias which where.exe
Tetapi mengembalikan beberapa baris jika ada sehingga menjadi
function which {where.exe command | select -first 1}
where.exe where
harus memberi tahu AndaC:\Windows\System32\where.exe
where.exe
sama dengan which -a
, karena akan mengembalikan semua executable yang cocok, bukan hanya yang pertama yang dieksekusi. Artinya, where.exe notepad
memberi c:\windows\notepad.exe
dan c:\windows\system32\notepad.exe
. Jadi ini sangat tidak cocok untuk formulir $(which command)
. (Masalah lain adalah bahwa ia akan mencetak pesan kesalahan yang bagus dan bermanfaat jika perintah tidak ditemukan, yang juga tidak akan berkembang dengan baik $()
- yang dapat diatasi dengan /Q
, tetapi tidak sebagai alias.)
where
tampaknya mencari variabel PATH sistem dan bukan variabel PATH shell saat ini. Lihat pertanyaan ini
Ini tampaknya melakukan apa yang Anda inginkan (saya menemukannya di http://huddledmasses.org/powershell-find-path/ ):
Function Find-Path($Path, [switch]$All = $false, [Microsoft.PowerShell.Commands.TestPathType]$type = "Any")
## You could comment out the function stuff and use it as a script instead, with this line:
#param($Path, [switch]$All = $false, [Microsoft.PowerShell.Commands.TestPathType]$type = "Any")
if($(Test-Path $Path -Type $type)) {
return $path
} else {
[string[]]$paths = @($pwd);
$paths += "$pwd;$env:path".split(";")
$paths = Join-Path $paths $(Split-Path $Path -leaf) | ? { Test-Path $_ -Type $type }
if($paths.Length -gt 0) {
if($All) {
return $paths;
} else {
return $paths[0]
}
}
}
throw "Couldn't find a matching path of type $type"
}
Set-Alias find Find-Path
Periksa PowerShell Yang Ini .
Kode yang disediakan di sana menyarankan ini:
($Env:Path).Split(";") | Get-ChildItem -filter notepad.exe
Coba where
perintah pada Windows 2003 atau yang lebih baru (atau Windows 2000 / XP jika Anda telah menginstal Resource Kit).
BTW, ini menerima lebih banyak jawaban dalam pertanyaan lain:
where
alias ke Where-Object
commandlet di Powershell, jadi mengetikkan where <item>
prompt Powershell tidak menghasilkan apa-apa. Jawaban ini benar-benar salah - sebagaimana dicatat dalam jawaban yang diterima dalam pertanyaan terkait pertama, untuk mendapatkan DOS where
, Anda perlu mengetik where.exe <item>
.
Saya memiliki which
fungsi lanjutan ini di profil PowerShell saya:
function which {
<#
.SYNOPSIS
Identifies the source of a PowerShell command.
.DESCRIPTION
Identifies the source of a PowerShell command. External commands (Applications) are identified by the path to the executable
(which must be in the system PATH); cmdlets and functions are identified as such and the name of the module they are defined in
provided; aliases are expanded and the source of the alias definition is returned.
.INPUTS
No inputs; you cannot pipe data to this function.
.OUTPUTS
.PARAMETER Name
The name of the command to be identified.
.EXAMPLE
PS C:\Users\Smith\Documents> which Get-Command
Get-Command: Cmdlet in module Microsoft.PowerShell.Core
(Identifies type and source of command)
.EXAMPLE
PS C:\Users\Smith\Documents> which notepad
C:\WINDOWS\SYSTEM32\notepad.exe
(Indicates the full path of the executable)
#>
param(
[String]$name
)
$cmd = Get-Command $name
$redirect = $null
switch ($cmd.CommandType) {
"Alias" { "{0}: Alias for ({1})" -f $cmd.Name, (. { which cmd.Definition } ) }
"Application" { $cmd.Source }
"Cmdlet" { "{0}: {1} {2}" -f $cmd.Name, $cmd.CommandType, (. { if ($cmd.Source.Length) { "in module {0}" -f $cmd.Source} else { "from unspecified source" } } ) }
"Function" { "{0}: {1} {2}" -f $cmd.Name, $cmd.CommandType, (. { if ($cmd.Source.Length) { "in module {0}" -f $cmd.Source} else { "from unspecified source" } } ) }
"Workflow" { "{0}: {1} {2}" -f $cmd.Name, $cmd.CommandType, (. { if ($cmd.Source.Length) { "in module {0}" -f $cmd.Source} else { "from unspecified source" } } ) }
"ExternalScript" { $cmd.Source }
default { $cmd }
}
}
Menggunakan:
function Which([string] $cmd) {
$path = (($Env:Path).Split(";") | Select -uniq | Where { $_.Length } | Where { Test-Path $_ } | Get-ChildItem -filter $cmd).FullName
if ($path) { $path.ToString() }
}
# Check if Chocolatey is installed
if (Which('cinst.bat')) {
Write-Host "yes"
} else {
Write-Host "no"
}
Atau versi ini, memanggil perintah asli di mana.
Versi ini juga berfungsi lebih baik, karena tidak terbatas pada file bat:
function which([string] $cmd) {
$where = iex $(Join-Path $env:SystemRoot "System32\where.exe $cmd 2>&1")
$first = $($where -split '[\r\n]')
if ($first.getType().BaseType.Name -eq 'Array') {
$first = $first[0]
}
if (Test-Path $first) {
$first
}
}
# Check if Curl is installed
if (which('curl')) {
echo 'yes'
} else {
echo 'no'
}
Jika Anda ingin comamnd yang menerima input dari pipa atau sebagai parameter, Anda harus mencoba ini:
function which($name) {
if ($name) { $input = $name }
Get-Command $input | Select-Object -ExpandProperty Path
}
salin-tempel perintah ke profil Anda ( notepad $profile
).
Contoh:
❯ echo clang.exe | which
C:\Program Files\LLVM\bin\clang.exe
❯ which clang.exe
C:\Program Files\LLVM\bin\clang.exe