PowerShell'de * Nix 'hangi' komutunun eşdeğeri?


404

PowerShell'e bir şeyin nerede olduğunu nasıl sorabilirim?

Örneğin, "hangi not defteri" ve notepad.exe dosyasının çalıştırıldığı dizini geçerli yollara göre döndürür.

Yanıtlar:


390

PowerShell'de profilimi özelleştirmeye başladığımda yaptığım ilk takma ad 'hangisi' idi.

New-Alias which get-command

Bunu profilinize eklemek için şunu yazın:

"`nNew-Alias which get-command" | add-content $profile

Son satırın başındaki `n, yeni satır olarak başlayacağından emin olmaktır.


1
Profil betiğinize koyabilirsiniz. Profiller hakkında daha fazla bilgi - msdn.microsoft.com/en-us/library/bb613488(VS.85).aspx
Steven Murawski

61
i gibi çalışan: Get-Command <command> | Format-Table Path, Nameböylece komut çok oturur yolu alabilirsiniz.
jrsconfitto

4
Her zaman yol yazmak için herhangi bir yolu var mı '| Biçim-Tablo Yolu, Adı '?
Guillaume

10
Unix tarzı davranışın size yol vermesini istiyorsanız, get-komutunun çıktısını yönlendirmeniz gerekir select -expandproperty Path.
Casey

5
(gcm <command>).definitionYalnızca yolları almak için kullanın . gcmiçin varsayılan takma addır Get-Command. Ayrıca, joker mesela kullanabilirsiniz: (gcm win*.exe).definition.
Sachin Joseph

165

İşte gerçek bir * nix eşdeğeri, yani * nix tarzı çıktı verir.

Get-Command <your command> | Select-Object -ExpandProperty Definition

Sadece aradığınla değiştir.

PS C:\> Get-Command notepad.exe | Select-Object -ExpandProperty Definition
C:\Windows\system32\notepad.exe

Profilinize eklediğinizde, diğer adları borularla kullanamazsınız çünkü takma ad yerine bir işlev kullanmak istersiniz:

function which($name)
{
    Get-Command $name | Select-Object -ExpandProperty Definition
}

Şimdi, profilinizi yeniden yüklediğinizde şunları yapabilirsiniz:

PS C:\> which notepad
C:\Windows\system32\notepad.exe

22
Bu alternatif sözdizimini kullanıyorum: "(Get-Command notepad) .definition"
Yann

2
@ B00merang Sözdizim harika - kesinlikle daha kısa - ama ne yazık ki, boru kaldırıldığında bile, aradığınız programın adını eklemezseniz, takma ad olarak eklenemez.
petrsnd

4
Bu eski bir gönderi, ancak burada Google tarafından gönderildiği takdirde (benim gibi), bu cevap kabul edilen yanıttan daha fazla Powershell komutu türüyle çalışır. Örneğin, üzerinde olmayan oktabir Powershell betiğine işaret eden bir takma okta.ps1adım var $PATH. Kabul edilen cevabı kullanmak komut dosyasının adını ( okta -> okta.ps1) döndürür . Bu tamam ama bana yerini söylemiyorokta.ps1 . Ancak bu cevabı kullanmak bana tüm yolu ( C:\Users\blah\etc\scripts\okta.ps1) verir. Yani benden +1.
skye --- kaptan

88

Genellikle sadece şunu yazarım:

gcm notepad

veya

gcm note*

gcm, Get-Command için varsayılan diğer addır.

Sistemimde gcm note * çıktıları:

[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

Dizini ve aradığınızla eşleşen komutu alırsınız.


onun biraz dağınık, ama özel fonksiyonlar ve keyfi bölünmelerden çok daha temiz
DevelopingChris

1
Powershell komut istemime "gcm notepad" yazdığımda, ilk iki sütunu ve boş olan 'ModuleName' adlı üçüncü bir sütunu alıyorum. Varsayılan olarak 'Tanım' sütununu listelemeyi nasıl zorlayacağınızı biliyor musunuz?
Piyush Soni

3
@PiyushSoni, muhtemelen PowerShell'in güncellenmiş bir sürümü nedeniyle. Diğer sütunları her zaman benzer bir şey yaparak görüntüleyebilirsiniz gcm note* | select CommandType, Name, Definition. Sık sık çalıştırırsanız, muhtemelen bir işleve sarmalısınız.
David Mohundro

40

Bu örneği deneyin:

(Get-Command notepad.exe).Path

2
Lütfen OP'nin sizi daha iyi anlayabilmesi için daha fazla kod veya açıklama ekleyin. Teşekkür ederim.
sshashank124

3
Daha az kod eklediğiniz için teşekkür ederim, böylece bunu bir kez hatırlayabilirim: P
albertjan

1
İstediğim bu! Gcm ile de çalışır:(gcm py.exe).path
Bill Agee

7

Hangi işlev için önerim:

function which($cmd) { get-command $cmd | % { $_.Path } }

PS C:\> which devcon

C:\local\code\bin\devcon.exe

Bu, kabul edilenden daha iyi bir cevaptır. Daha iyi çıktı sağlamak için yukarıda önerilen işlem sonrası sonekleri eklemenizi sağlar; bir takma ad yapmaz.
BobHy

5

Unix whichile hızlı ve kirli bir maç

New-Alias which where.exe

Ama eğer varsa birden fazla satır döndürür, o zaman olur

function which {where.exe command | select -first 1}

1
where.exe wheresöylemeliyimC:\Windows\System32\where.exe
Chris F Carroll

1
where.exesadece çalıştırılacak ilk dosyayı değil, eşleşen tüm yürütülebilir dosyaları which -ageri vereceği için eşdeğerdir . Yani, verir ve . Dolayısıyla bu özellikle form için uygun değildir . (Başka bir sorun da komut bulunmazsa, güzel, yararlı hata mesajı yazdırılır da güzel genişlemediğini edileceği orandadır - Bunda çözülebilir ancak bir takma ad olarak.)where.exe notepadc:\windows\notepad.exec:\windows\system32\notepad.exe$(which command)$()/Q
Jeroen Mostert

nokta alınır. Cevabı düzenledim ama evet artık çok temiz bir çözüm değil
Chris F Carroll

1
Lütfen wheregeçerli kabuk PATH değişkenini değil sistem PATH değişkenini araştırıyor gibi görünüyor. Bu soruya
Leonardo

3

Bu istediğinizi yapıyor gibi görünüyor ( http://huddledmasses.org/powershell-find-path/ üzerinde buldum ):

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

Ancak herhangi bir dosya (tür) ile çalıştığı ve cmdlet'ler, işlevler veya takma adlar bulamadığı için gerçekten "hangi" değil
Jaykul

3

Hangi PowerShell'i kontrol edin .

Burada sağlanan kod şunu önerir:

($Env:Path).Split(";") | Get-ChildItem -filter notepad.exe

2
Yıllar geçtiğini biliyorum, ama yolumda "% systemroot% \ system32 \ ..." vardı ve PowerShell bu ortam değişkenini genişletmiyor ve bunu yaparken hatalar atıyor.
TessellatingHeckler

3

Ben Get-Command | Format-Listikisi için takma ad kullanarak ve daha kısa, ve sadece için powershell.exe:

gcm powershell | fl

Bunun gibi takma adlar bulabilirsiniz:

alias -definition Format-List

Sekme tamamlama ile çalışır gcm.


2

whereWindows 2003 veya sonraki sürümlerde (veya bir Kaynak Seti taktıysanız Windows 2000 / XP) komutu deneyin .

BTW, bu diğer sorularda daha fazla cevap aldı:

Windows'da 'hangisinin' eşdeğeri var mı?

Unix whichkomutuna eşdeğer PowerShell ?


4
whereWhere-ObjectPowershell'deki komut dosyasının diğer adlarıdır, bu nedenle where <item>bir Powershell istemine yazmak hiçbir şey vermez. Dolayısıyla bu cevap tamamen yanlıştır - ilk bağlantılı sorudaki kabul edilen cevapta belirtildiği gibi, DOS'u almak için whereyazmanız gerekir where.exe <item>.
Ian Kemp

0

whichPowerShell profilimde bu gelişmiş işlev var :

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 }
    }
}

0

kullanın:

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"
}

Veya bu sürüm, orjinal where komutunu çağırıyor.

Bu sürüm, bat dosyalarıyla sınırlı olmadığı için daha iyi çalışır:

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'
}

0

Her ikisinin de boru hattından veya parametre olarak girişi kabul eden bir komuta istiyorsanız, bunu denemelisiniz:

function which($name) {
    if ($name) { $input = $name }
    Get-Command $input | Select-Object -ExpandProperty Path
}

komutu profilinize kopyalayın ( notepad $profile).

Örnekler:

 echo clang.exe | which
C:\Program Files\LLVM\bin\clang.exe

 which clang.exe
C:\Program Files\LLVM\bin\clang.exe
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.