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.
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.
Réponses:
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.
Get-Command <command> | Format-Table Path, Name
donc je peux aussi trouver le chemin où se trouve la commande.
select -expandproperty Path
.
(gcm <command>).definition
pour obtenir le (s) chemin (s) uniquement. gcm
est l'alias par défaut de Get-Command
. Vous pouvez également utiliser des caractères génériques, par exemple: (gcm win*.exe).definition
.
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
okta
qui pointe vers un script Powershell nommé okta.ps1
qui 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.
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.
gcm note* | select CommandType, Name, Definition
. Si vous l'exécutez souvent, vous devriez probablement l'envelopper dans une fonction.
Essayez cet exemple:
(Get-Command notepad.exe).Path
(gcm py.exe).path
Ma proposition pour la fonction Which:
function which($cmd) { get-command $cmd | % { $_.Path } }
PS C:\> which devcon
C:\local\code\bin\devcon.exe
Une correspondance rapide et sale avec Unix which
est
New-Alias which where.exe
Mais il renvoie plusieurs lignes si elles existent, alors cela devient
function which {where.exe command | select -first 1}
where.exe where
devrait vous direC:\Windows\System32\where.exe
where.exe
est équivalent à which -a
, car il rendra tous les exécutables correspondants, pas seulement le premier à exécuter. Autrement dit, where.exe notepad
donne c:\windows\notepad.exe
et 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.)
where
semble rechercher la variable PATH système et non la variable PATH shell actuelle. Voir cette question
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
Vérifiez ce PowerShell qui .
Le code fourni ici suggère ceci:
($Env:Path).Split(";") | Get-ChildItem -filter notepad.exe
Essayez la where
commande 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:
where
alias du Where-Object
commandlet 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>
.
J'ai cette which
fonction 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 }
}
}
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'
}
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