Équivalent de * Nix 'quelle' commande dans PowerShell?

405

Comment demander à PowerShell où se trouve quelque chose?

Par exemple, "quel bloc-notes" et il renvoie le répertoire à partir duquel le bloc-notes est exécuté en fonction des chemins d'accès actuels.

DevelopingChris
la source

Réponses:

392

Le tout premier alias que j'ai créé une fois que j'ai commencé à personnaliser mon profil dans PowerShell était «qui».

New-Alias which get-command

Pour ajouter ceci à votre profil, tapez ceci:

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

Le `n au début de la dernière ligne est pour s'assurer qu'il commencera comme une nouvelle ligne.

halr9000
la source
1
Vous pouvez le mettre dans votre script de profil. Plus d'informations sur les profils - msdn.microsoft.com/en-us/library/bb613488(VS.85).aspx
Steven Murawski
62
j'aime courir: Get-Command <command> | Format-Table Path, Namedonc je peux aussi trouver le chemin où se trouve la commande.
jrsconfitto
4
Existe-t-il un moyen d'avoir le chemin tout le temps sans taper '| Format-Table Path, Name '?
Guillaume
10
Si vous voulez que le comportement de style Unix vous donne le chemin dont vous aurez besoin pour diriger la sortie de get-command select -expandproperty Path.
Casey
5
Utilisez (gcm <command>).definitionpour obtenir le (s) chemin (s) uniquement. gcmest l'alias par défaut de Get-Command. Vous pouvez également utiliser des caractères génériques, par exemple: (gcm win*.exe).definition.
Sachin Joseph
165

Voici un véritable équivalent * nix, c'est-à-dire qu'il donne une sortie de style * nix.

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

Remplacez simplement par ce que vous cherchez.

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

Lorsque vous l'ajoutez à votre profil, vous souhaiterez utiliser une fonction plutôt qu'un alias car vous ne pouvez pas utiliser d'alias avec des canaux:

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

Maintenant, lorsque vous rechargez votre profil, vous pouvez le faire:

PS C:\> which notepad
C:\Windows\system32\notepad.exe
petrsnd
la source
22
J'utilise cette syntaxe alternative: "(Bloc-notes Get-Command) .definition"
Yann
2
@ B00merang Votre syntaxe est géniale - certainement plus concise - mais malheureusement, même avec le canal supprimé, il ne peut pas être ajouté en tant qu'alias, sauf si vous incluez le nom du programme que vous recherchez.
petrsnd
4
Il s'agit d'un ancien message, mais si quelqu'un est envoyé ici par Google (comme je l'étais), cette réponse fonctionne avec plus de types de commandes Powershell que la réponse acceptée. Par exemple, j'ai un alias nommé oktaqui pointe vers un script Powershell nommé okta.ps1qui n'est pas sur mon $PATH. L'utilisation de la réponse acceptée renvoie le nom du script ( okta -> okta.ps1). C'est OK mais ça ne me dit pas où okta.ps1. L'utilisation de cette réponse, cependant, me donne le chemin complet ( C:\Users\blah\etc\scripts\okta.ps1). Donc +1 de moi.
skye --- capitaine
88

Je tape habituellement juste:

gcm notepad

ou

gcm note*

gcm est l'alias par défaut de Get-Command.

Sur mon système, gcm note * affiche:

[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

Vous obtenez le répertoire et la commande correspondant à ce que vous recherchez.

David Mohundro
la source
son un peu désordonné, mais beaucoup plus propre que les fonctions personnalisées et les divisions arbitraires
DevelopingChris
1
Lorsque je tape «bloc-notes gcm» dans mon invite de commande powershell, je reçois simplement les deux premières colonnes et une troisième colonne appelée «ModuleName» qui est vide. Savez-vous comment le forcer à lister la colonne 'Définition' par défaut?
Piyush Soni
3
@PiyushSoni est probablement dû à une version mise à jour de PowerShell. Vous pouvez toujours afficher les autres colonnes en faisant quelque chose comme gcm note* | select CommandType, Name, Definition. Si vous l'exécutez souvent, vous devriez probablement l'envelopper dans une fonction.
David Mohundro
40

Essayez cet exemple:

(Get-Command notepad.exe).Path
thesqldev
la source
2
Veuillez ajouter plus de code ou d'explication pour que l'OP puisse mieux vous comprendre. Je vous remercie.
sshashank124
3
Merci d'avoir ajouté moins de code pour que je puisse m'en souvenir pour une fois: P
albertjan
1
Voilà ce que je voulais! Il fonctionne également avec gcm:(gcm py.exe).path
Bill Agee
7

Ma proposition pour la fonction Which:

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

PS C:\> which devcon

C:\local\code\bin\devcon.exe
VortiFred
la source
C'est une meilleure réponse que celle acceptée. Il vous permet d'ajouter les suffixes de post-traitement suggérés ci-dessus pour fournir une meilleure sortie; un alias non.
BobHy
5

Une correspondance rapide et sale avec Unix whichest

New-Alias which where.exe

Mais il renvoie plusieurs lignes si elles existent, alors cela devient

function which {where.exe command | select -first 1}
Chris F Carroll
la source
1
where.exe wheredevrait vous direC:\Windows\System32\where.exe
Chris F Carroll
1
where.exeest équivalent à which -a, car il rendra tous les exécutables correspondants, pas seulement le premier à exécuter. Autrement dit, where.exe notepaddonne c:\windows\notepad.exeet c:\windows\system32\notepad.exe. Ce n'est donc pas particulièrement adapté à la forme $(which command). (Un autre problème est qu'il affichera un joli message d'erreur utile si la commande n'est pas trouvée, qui ne se développera pas non plus correctement $()- cela peut être résolu /Q, mais pas comme un alias.)
Jeroen Mostert
point pris. J'ai édité la réponse mais oui ce n'est plus une solution si soignée
Chris F Carroll
1
Veuillez noter que wheresemble rechercher la variable PATH système et non la variable PATH shell actuelle. Voir cette question
Leonardo
3

Cela semble faire ce que vous voulez (je l'ai trouvé sur 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
Nicolas
la source
Mais ce n'est pas vraiment "qui" car il fonctionne avec n'importe quel fichier (type) et ne trouve pas d'applets de commande, de fonctions ou d'alias
Jaykul
3

Vérifiez ce PowerShell qui .

Le code fourni ici suggère ceci:

($Env:Path).Split(";") | Get-ChildItem -filter notepad.exe
tzot
la source
2
Je sais que cela fait des années, mais mon chemin avait "% systemroot% \ system32 \ ..." et PowerShell ne développe pas cette variable d'environnement et génère des erreurs en faisant cela.
TessellatingHeckler
3

J'aime Get-Command | Format-List, ou plus court, utiliser des alias pour les deux et uniquement pour powershell.exe:

gcm powershell | fl

Vous pouvez trouver des alias comme celui-ci:

alias -definition Format-List

La complétion des onglets fonctionne avec gcm.

js2010
la source
2

Essayez la wherecommande sous Windows 2003 ou version ultérieure (ou Windows 2000 / XP si vous avez installé un kit de ressources).

BTW, cela a reçu plus de réponses dans d'autres questions:

Existe-t-il un équivalent de «lequel» sous Windows?

PowerShell équivalent à la whichcommande Unix ?

Anonyme
la source
4
wherealias du Where-Objectcommandlet dans Powershell, donc la saisie where <item>d'une invite Powershell ne donne rien. Cette réponse est donc complètement incorrecte - comme indiqué dans la réponse acceptée dans la première question liée, pour obtenir le DOS where, vous devez taper where.exe <item>.
Ian Kemp
0

J'ai cette whichfonction avancée dans mon profil 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 }
    }
}
Jeff Zeitlin
la source
0

Utilisation:

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

Ou cette version, en appelant la commande where d'origine.

Cette version fonctionne également mieux, car elle n'est pas limitée aux fichiers 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'
}
Jérôme
la source
0

Si vous voulez un comamnd qui accepte les entrées du pipeline ou en tant que paramètre, vous devriez essayer ceci:

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

copiez-collez la commande dans votre profil ( notepad $profile).

Exemples:

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

 which clang.exe
C:\Program Files\LLVM\bin\clang.exe
Amin
la source