Equivalente di * Nix 'quale' comando in PowerShell?


405

Come posso chiedere a PowerShell dove si trova qualcosa?

Ad esempio, "quale blocco note" e restituisce la directory da cui viene eseguito notepad.exe in base ai percorsi correnti.

Risposte:


392

Il primissimo alias che ho fatto una volta che ho iniziato a personalizzare il mio profilo in PowerShell è stato 'quale'.

New-Alias which get-command

Per aggiungere questo al tuo profilo, digita questo:

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

La `n all'inizio dell'ultima riga è quella di assicurarsi che inizi come una nuova riga.


1
Puoi metterlo nello script del tuo profilo. Altro sui profili - msdn.microsoft.com/en-us/library/bb613488(VS.85).aspx
Steven Murawski,

62
mi piace correre: Get-Command <command> | Format-Table Path, Namecosì posso ottenere il percorso in cui si trova anche il comando.
jrsconfitto,

4
Esiste un modo per avere sempre il percorso senza digitare '| Percorso tabella formato, nome "?
Guillaume,

10
Se vuoi che il comportamento in stile Unix ti dia il percorso, dovrai reindirizzare l'output di get-command select -expandproperty Path.
Casey,

5
Utilizzare (gcm <command>).definitionper ottenere solo i percorsi. gcmè l'alias predefinito per Get-Command. È inoltre possibile utilizzare i caratteri jolly, ad esempio: (gcm win*.exe).definition.
Sachin Joseph,

165

Ecco un equivalente * nix effettivo, ovvero fornisce un output in stile * nix.

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

Sostituisci semplicemente con quello che stai cercando.

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

Quando lo aggiungi al tuo profilo, ti consigliamo di utilizzare una funzione anziché un alias perché non puoi utilizzare gli alias con pipe:

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

Ora, quando ricarichi il tuo profilo puoi farlo:

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

22
Uso questa sintassi alternativa: "(Blocco note Get-Command) .definition"
Yann

2
@ B00merang La tua sintassi è ottima - sicuramente più concisa - ma sfortunatamente, anche con la pipe rimossa, non può essere aggiunta come alias a meno che tu non includa il nome del programma che stai cercando.
petrsnd,

4
Questo è un vecchio post, ma nel caso in cui qualcuno venga inviato qui da Google (come lo ero io), questa risposta funziona con più tipi di comandi Powershell rispetto alla risposta accettata. Ad esempio, ho un alias chiamato oktache punta a uno script Powershell chiamato okta.ps1che non è sul mio $PATH. L'uso della risposta accettata restituisce il nome dello script ( okta -> okta.ps1). Questo è OK ma non mi dice la posizione di okta.ps1. L'uso di questa risposta, tuttavia, mi dà l'intero percorso ( C:\Users\blah\etc\scripts\okta.ps1). Quindi +1 da me.
skye --- capitano

88

Di solito scrivo solo:

gcm notepad

o

gcm note*

gcm è l'alias predefinito per Get-Command.

Sul mio sistema, gcm note * genera:

[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

Ottieni la directory e il comando che corrisponde a ciò che stai cercando.


è un po 'disordinato, ma molto più pulito di funzioni personalizzate e divisioni arbitrarie
DevelopingChris

1
Quando digito "gcm notepad" nel mio prompt dei comandi di PowerShell, ottengo solo le prime due colonne e una terza colonna denominata "ModuleName" che è vuota. Sai come forzarlo a elencare la colonna 'Definizione' per impostazione predefinita?
Piyush Soni,

3
@PiyushSoni probabilmente a causa di una versione aggiornata di PowerShell. Puoi sempre visualizzare le altre colonne facendo qualcosa di simile gcm note* | select CommandType, Name, Definition. Se lo esegui spesso, probabilmente dovresti avvolgerlo in una funzione.
David Mohundro,

40

Prova questo esempio:

(Get-Command notepad.exe).Path

2
Aggiungi altro codice o spiegazione in modo che l'OP possa capirti meglio. Grazie.
sshashank124

3
Grazie per aver aggiunto meno codice in modo da poterlo ricordare per una volta: P
albertjan,

1
Questo è quello che volevo! Funziona anche con gcm:(gcm py.exe).path
Bill Agee,

7

La mia proposta per la funzione Which:

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

PS C:\> which devcon

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

Questa è una risposta migliore di quella accettata. Consente di aggiungere i suffissi di postelaborazione suggeriti sopra per fornire un output migliore; un alias no.
Bob,

5

Una partita veloce e sporca con Unix whichè

New-Alias which where.exe

Ma restituisce più righe se esistono, quindi diventa

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

1
where.exe wheredovrei dirtiC:\Windows\System32\where.exe
Chris F Carroll l'

1
where.exeè equivalente a which -a, poiché restituirà tutti gli eseguibili corrispondenti, non solo il primo da eseguire. Cioè, where.exe notepadc:\windows\notepad.exee c:\windows\system32\notepad.exe. Quindi questo è particolarmente non è adatto per il modulo $(which command). (Un altro problema è che stamperà un messaggio di errore utile e utile se il comando non viene trovato, che non si espanderà bene in $()- che può essere risolto /Q, ma non come alias.)
Jeroen Mostert

punto preso. Ho modificato la risposta, ma sì, non è più una soluzione così accurata
Chris F Carroll

1
Si noti che wheresembra cercare la variabile PATH di sistema e non la variabile PATH della shell corrente. Vedi questa domanda
Leonardo,

3

Questo sembra fare quello che vuoi (l'ho trovato su 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

Ma non è proprio "quale" dato che funziona con qualsiasi file (tipo) e non trova cmdlet, funzioni o alias
Jaykul,

3

Controlla questo PowerShell Quale .

Il codice fornito suggerisce questo:

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

2
So che sono passati anni, ma il mio percorso aveva "% systemroot% \ system32 \ ..." e PowerShell non espande quella variabile d'ambiente e genera errori nel fare ciò.
Tessellating Heckler,

3

Mi piace Get-Command | Format-List, o più breve, usare gli alias per i due e solo per powershell.exe:

gcm powershell | fl

Puoi trovare alias in questo modo:

alias -definition Format-List

Il completamento della scheda funziona con gcm.


2

Prova il where comando su Windows 2003 o versioni successive (o Windows 2000 / XP se hai installato un Resource Kit).

A proposito, questo ha ricevuto più risposte in altre domande:

Esiste un equivalente di "quale" su Windows?

PowerShell equivalente al whichcomando Unix ?


4
wherealias del Where-Objectcomando in Powershell, quindi digitare where <item>un prompt di Powershell non produce nulla. Questa risposta è quindi completamente errata - come indicato nella risposta accettata nella prima domanda collegata, per ottenere il DOS where, è necessario digitare where.exe <item>.
Ian Kemp,

0

Ho questa whichfunzione avanzata nel mio profilo PowerShell:

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

Uso:

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

O questa versione, chiamando il comando where originale.

Anche questa versione funziona meglio, perché non si limita ai 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'
}

0

Se si desidera un comamnd che accetta input dalla pipeline o come parametro, si dovrebbe provare questo:

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

copia-incolla il comando sul tuo profilo (notepad $profile ).

Esempi:

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

 which clang.exe
C:\Program Files\LLVM\bin\clang.exe
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.