Làm cách nào để hỏi PowerShell một cái gì đó ở đâu?
Ví dụ: "notepad" và nó trả về thư mục nơi notepad.exe được chạy từ các đường dẫn hiện tại.
Làm cách nào để hỏi PowerShell một cái gì đó ở đâu?
Ví dụ: "notepad" và nó trả về thư mục nơi notepad.exe được chạy từ các đường dẫn hiện tại.
Câu trả lời:
Bí danh đầu tiên tôi tạo ra khi tôi bắt đầu tùy chỉnh hồ sơ của mình trong PowerShell là 'cái đó'.
New-Alias which get-command
Để thêm nó vào hồ sơ của bạn, gõ này:
"`nNew-Alias which get-command" | add-content $profile
`N ở đầu dòng cuối cùng là để đảm bảo nó sẽ bắt đầu như một dòng mới.
Get-Command <command> | Format-Table Path, Name
vì vậy tôi có thể nhận được đường dẫn mà lệnh cũng nằm.
select -expandproperty Path
.
(gcm <command>).definition
để chỉ nhận (các) đường dẫn. gcm
là bí danh mặc định cho Get-Command
. Bạn cũng có thể sử dụng ký tự đại diện, ví dụ : (gcm win*.exe).definition
.
Đây là một tương đương * nix thực tế, tức là nó cho đầu ra kiểu * nix.
Get-Command <your command> | Select-Object -ExpandProperty Definition
Chỉ cần thay thế bằng bất cứ điều gì bạn đang tìm kiếm.
PS C:\> Get-Command notepad.exe | Select-Object -ExpandProperty Definition
C:\Windows\system32\notepad.exe
Khi bạn thêm nó vào hồ sơ của mình, bạn sẽ muốn sử dụng một chức năng thay vì bí danh vì bạn không thể sử dụng bí danh với các đường ống:
function which($name)
{
Get-Command $name | Select-Object -ExpandProperty Definition
}
Bây giờ, khi bạn tải lại hồ sơ của bạn, bạn có thể làm điều này:
PS C:\> which notepad
C:\Windows\system32\notepad.exe
okta
trỏ đến tập lệnh Powershell có tên okta.ps1
không phải trên tập lệnh của tôi $PATH
. Sử dụng câu trả lời được chấp nhận trả về tên tập lệnh ( okta -> okta.ps1
). Điều này là ổn nhưng nó không cho tôi biết vị trí của okta.ps1
. Tuy nhiên, sử dụng câu trả lời này cho tôi toàn bộ đường dẫn ( C:\Users\blah\etc\scripts\okta.ps1
). Vì vậy, +1 từ tôi.
Tôi thường chỉ gõ:
gcm notepad
hoặc là
gcm note*
gcm là bí danh mặc định cho Get-Command.
Trên hệ thống của tôi, ghi chú gcm * đầu ra:
[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
Bạn nhận được thư mục và lệnh phù hợp với những gì bạn đang tìm kiếm.
gcm note* | select CommandType, Name, Definition
. Nếu bạn chạy nó thường xuyên, có lẽ bạn nên bọc nó trong một chức năng.
Hãy thử ví dụ này:
(Get-Command notepad.exe).Path
(gcm py.exe).path
Đề xuất của tôi cho chức năng nào:
function which($cmd) { get-command $cmd | % { $_.Path } }
PS C:\> which devcon
C:\local\code\bin\devcon.exe
Một trận đấu nhanh và bẩn với Unix which
là
New-Alias which where.exe
Nhưng nó trả về nhiều dòng nếu chúng tồn tại như vậy thì nó trở thành
function which {where.exe command | select -first 1}
where.exe where
nên nói với bạnC:\Windows\System32\where.exe
where.exe
tương đương với which -a
, vì nó sẽ trả lại tất cả các tệp thực thi phù hợp, không chỉ là tệp đầu tiên được thực thi. Đó là, where.exe notepad
cho c:\windows\notepad.exe
và c:\windows\system32\notepad.exe
. Vì vậy, điều này đặc biệt không phù hợp với hình thức $(which command)
. (Một vấn đề khác là nó sẽ in một thông báo lỗi hữu ích nếu không tìm thấy lệnh, nó cũng sẽ không mở rộng độc đáo $()
- có thể được khắc phục /Q
, nhưng không phải là bí danh.)
where
dường như tìm kiếm biến PATH của hệ thống chứ không phải biến PATH của vỏ hiện tại. Xem câu hỏi này
Điều này dường như làm những gì bạn muốn (tôi tìm thấy nó trên 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
Kiểm tra PowerShell này .
Mã được cung cấp ở đó gợi ý điều này:
($Env:Path).Split(";") | Get-ChildItem -filter notepad.exe
Thử where
lệnh trên Windows 2003 trở lên (hoặc Windows 2000 / XP nếu bạn đã cài đặt Bộ tài nguyên).
BTW, điều này nhận được nhiều câu trả lời hơn trong các câu hỏi khác:
where
bí danh cho Where-Object
lệnh trong Powershell, vì vậy gõ where <item>
vào dấu nhắc Powershell không mang lại kết quả gì. Do đó, câu trả lời này hoàn toàn không chính xác - như đã lưu ý trong câu trả lời được chấp nhận trong câu hỏi được liên kết đầu tiên, để có được DOS where
, bạn cần phải gõ where.exe <item>
.
Tôi có which
chức năng nâng cao này trong hồ sơ PowerShell của mình:
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 }
}
}
Sử dụng:
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"
}
Hoặc phiên bản này, gọi lệnh gốc ở đâu.
Phiên bản này cũng hoạt động tốt hơn, vì nó không giới hạn ở các tập tin 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'
}
Nếu bạn muốn một comamnd mà cả hai chấp nhận đầu vào từ đường ống hoặc là paramater, bạn nên thử điều này:
function which($name) {
if ($name) { $input = $name }
Get-Command $input | Select-Object -ExpandProperty Path
}
sao chép-dán lệnh vào hồ sơ của bạn ( notepad $profile
).
Ví dụ:
❯ echo clang.exe | which
C:\Program Files\LLVM\bin\clang.exe
❯ which clang.exe
C:\Program Files\LLVM\bin\clang.exe