มี 'เทียบเท่า' ในบรรทัดคำสั่งของ Windows หรือไม่


2351

เนื่องจากบางครั้งฉันมีปัญหาเกี่ยวกับเส้นทางที่หนึ่งในสคริปต์ cmd ของฉันถูกซ่อน (เงา) โดยโปรแกรมอื่น (ก่อนหน้าบนเส้นทาง) ฉันต้องการหาเส้นทางแบบเต็มไปยังโปรแกรมบนบรรทัดคำสั่งของ Windows เพียงแค่ชื่อ

มีเทียบเท่ากับคำสั่ง UNIX 'ซึ่ง'?

บน UNIX which commandพิมพ์พา ธ แบบเต็มของคำสั่งที่กำหนดเพื่อค้นหาและแก้ไขปัญหาการแรเงาเหล่านี้ได้อย่างง่ายดาย


3
Foredecker: "ซึ่ง" การค้นหาเส้นทางสำหรับการปฏิบัติการที่จะทำงานถ้าคุณพิมพ์คำสั่งที่เปลือกพรอมต์
เกร็ก Hewgill

3
ตัวอย่างเช่นหากคุณติดตั้ง Java 5 เวอร์ชันและคุณไม่ทราบว่ากำลังใช้งานเวอร์ชันใดอยู่คุณสามารถพิมพ์ "java ชนิดใด" และให้เส้นทางกับไบนารี
ninesided

9
@Foredecker นายบอกว่ามันเป็น "ที่ไหน" ใน Win2k3 แต่ Win2k3 ไม่ได้เป็นส่วนหนึ่งของคำถาม หาก "ที่ไหน" ไม่ได้อยู่ใน Windows รุ่นอื่น ๆ คำตอบอื่น ๆ ก็ใช้ได้เช่นกัน IMNSHO คำตอบที่ใช้ได้กับ Windows ทุกรุ่นนั้นดีที่สุด นอกจากนี้คำตอบอื่น ๆ ก็ไม่ผิดเพียงแค่วิธีการที่แตกต่างกัน
paxdiablo

36
ฉันรู้ว่าคำถามนี้เกิดขึ้นก่อนที่ SuperUser แต่อาจเป็นของที่นั่น
palswim

16
ไม่มีwhichคำสั่งใน Unix มาตรฐาน ยูทิลิตี้ POSIX typeคือ C เชลล์มีคำสั่งที่และบางระบบมีมันเป็นปฏิบัติการภายนอก ยกตัวอย่างเช่นใน Debian Linux, มาจากแพคเกจที่เรียกว่าwhich debutilsภายนอกwhichนี้ไม่ "เห็น" เชลล์บิวด์อินชื่อแทนหรือฟังก์ชัน typeทำ; Bash's typeมีตัวเลือกในการระงับและทำการค้นหาเส้นทาง
Kaz

คำตอบ:


2550

Windows Server 2003 และใหม่กว่า (เช่นอะไรหลังจาก Windows XP 32 บิต) ให้where.exeโปรแกรมที่ทำบางสิ่งwhichแม้ว่ามันจะตรงกับไฟล์ทุกประเภทไม่เพียงคำสั่งปฏิบัติการ (มันไม่ตรงกับในตัวคำสั่งเปลือกเช่นcd.) มันแม้จะยอมรับสัญลักษณ์เพื่อwhere nt*พบไฟล์ทั้งหมดของคุณในไดเรกทอรีปัจจุบันและมีชื่อขึ้นต้นด้วย%PATH%nt

ลองwhere /?ขอความช่วยเหลือ

โปรดทราบว่า Windows PowerShell กำหนดwhereเป็นชื่อแทนสำหรับcmdletดังนั้นหากคุณต้องการคุณจะต้องพิมพ์ชื่อเต็มแทนถนัดขยายWhere-Objectwhere.exe.exe


30
ไม่เพราะgrepตรวจสอบเนื้อหาของอินพุตซึ่งคุณต้องระบุอย่างชัดเจน ซึ่งและwhere.exeเพียงมองไปที่ชื่อของไฟล์ที่อยู่ในชุดของไดเรกทอรีที่ตั้งอยู่ในตัวแปรสภาพแวดล้อมเส้นทาง
Michael Ratanapintha

12
@ Ajedi32 - ถูกต้องซึ่งไม่ได้อยู่ใน XP อย่างที่ฉันบอกว่า "Windows Server 2003 และใหม่กว่า"
Michael Ratanapintha

24
ใช้งานได้ใน Windows 8
ปล้น

57
ระวังว่าสิ่งนี้จะไม่ทำงานใน PowerShellเว้นแต่ว่าคุณจะพิมพ์ where.exe
JonnyRaa

17
จำไว้ว่าwhere.exeไม่ใช่ตัวเชลล์คุณจำเป็นต้องมี%windir%\system32ในตัวของคุณ%PATH%- ซึ่งอาจไม่เป็นเช่นนั้นเนื่องจากการใช้งานwhereแนะนำว่าคุณอาจกำลังประสบปัญหากับเส้นทางของคุณ!
Tomasz Gandor

288

ในขณะที่ Windows รุ่นที่ใหม่กว่ามีwhereคำสั่งคุณสามารถทำได้ด้วย Windows XP โดยใช้ตัวดัดแปลงตัวแปรสภาพแวดล้อมดังต่อไปนี้:

c:\> for %i in (cmd.exe) do @echo.   %~$PATH:i
   C:\WINDOWS\system32\cmd.exe

c:\> for %i in (python.exe) do @echo.   %~$PATH:i
   C:\Python25\python.exe

คุณไม่ต้องการเครื่องมือพิเศษใด ๆ และไม่ จำกัด เพียงPATHเพราะคุณสามารถแทนที่ตัวแปรสภาพแวดล้อมใด ๆ (ในรูปแบบพา ธ , แน่นอน) ที่คุณต้องการใช้


และถ้าคุณต้องการส่วนเสริมที่สามารถรองรับนามสกุลทั้งหมดใน PATHEXT (เช่นเดียวกับที่ Windows ทำเอง) สิ่งนี้จะทำเคล็ดลับ:

@echo off
setlocal enableextensions enabledelayedexpansion

:: Needs an argument.

if "x%1"=="x" (
    echo Usage: which ^<progName^>
    goto :end
)

:: First try the unadorned filenmame.

set fullspec=
call :find_it %1

:: Then try all adorned filenames in order.

set mypathext=!pathext!
:loop1
    :: Stop if found or out of extensions.

    if "x!mypathext!"=="x" goto :loop1end

    :: Get the next extension and try it.

    for /f "delims=;" %%j in ("!mypathext!") do set myext=%%j
    call :find_it %1!myext!

:: Remove the extension (not overly efficient but it works).

:loop2
    if not "x!myext!"=="x" (
        set myext=!myext:~1!
        set mypathext=!mypathext:~1!
        goto :loop2
    )
    if not "x!mypathext!"=="x" set mypathext=!mypathext:~1!

    goto :loop1
:loop1end

:end
endlocal
goto :eof

:: Function to find and print a file in the path.

:find_it
    for %%i in (%1) do set fullspec=%%~$PATH:i
    if not "x!fullspec!"=="x" @echo.   !fullspec!
    goto :eof

จริง ๆ แล้วมันคืนความเป็นไปได้ทั้งหมด แต่คุณสามารถปรับแต่งมันได้อย่างง่ายดายสำหรับกฎการค้นหาที่เฉพาะเจาะจง


7
เฮ้ฉันหวังว่าฉันจะได้เรียนรู้สิ่งนั้น! น่าเสียดายที่มันใช้ไม่ได้กับ MS-DOS หรือ Win9x (นั่นคือคอมมิชชัน) (เรย์มอนด์เฉินมีเวอร์ชั่น "ซับซ้อน" มากกว่านี้คุณสามารถเปลี่ยนเป็นแบตช์ไฟล์: blogs.msdn.com/oldnewthing/archive/2005/01/20/357225.aspx )
Michael

110
@Michael หากคุณยังคงใช้ DOS หรือ Win95 การค้นหาไฟล์เอ็กซีคิ้วท์บนเส้นทางคือ อย่างน้อยปัญหาของคุณ :-)
paxdiablo

หน้าต่างตระหนักมากกว่า .exe เป็นปฏิบัติการ ครั้งสุดท้ายที่ฉันเขียนโค้ดwhichกลับมาในวัน W95 / DOS amdittedly ลำดับการค้นหาคือ - dir ปัจจุบันจากนั้นแต่ละเส้นทาง dir สำหรับ cmd.com จากนั้น cmd.exe จากนั้น cmd.bat ดังนั้นแม้กระทั่ง cmd.bat ใน dir ปัจจุบันคือ ดำเนินการ befroe cmd.exe ทุกที่ในเส้นทาง
Mawg พูดว่าคืนสถานะโมนิก้า

3
@mawg ต้นฉบับมาจากที่ที่คุณรู้จักส่วนขยายเนื่องจากเป็นส่วนที่แสดงภายใต้ UNIX (ซึ่งไม่มีการใช้กลอุบายเพิ่มส่วนขยาย) ตอนนี้ฉันได้เพิ่มอันที่สามารถทำสิ่งที่คุณต้องการ แต่มันไม่ได้เป็นคำสั่งง่ายๆอีกต่อไปเป็นสคริปต์ ก่อนอื่นให้ลองคำสั่งที่ไม่มีการตกแต่งจากนั้นแต่ละส่วนขยาย หวังว่าจะช่วย คุณสามารถปรับแต่งตามความต้องการของคุณตามที่เห็นสมควร (หากคุณต้องการลำดับการค้นหาเช่นเดียวกับ Windows ตัวอย่างเช่นอันนี้แสดงความเป็นไปได้ทั้งหมด)
paxdiablo

2
หากต้องการเปลี่ยนให้เป็นสคริปต์แบบแบตช์ให้สร้างไฟล์ชื่อ "which.bat": @echo off for %%i in (%1) do @echo. %%~$PATH:%i เพื่อเพิ่มลงในสคริปต์ alias.bat ที่คุณโหลดทุกครั้งที่คุณเรียกใช้ cmd.exe (ใส่สคริปต์ด้านบนในไดเรกทอรีใหม่ชื่อ C: \ usr \ aliases): DOSKEY which=C:\usr\aliases\which.bat $* จากนั้นคุณสามารถสร้างสคริปต์เพื่อเปิด cmd.exe ด้วยไฟล์ alias.bat: cmd.exe /K E:\usr\aliases\alias.bat
Brad T.

151

ภายใต้ PowerShell, Get-Commandจะพบ executables $Env:PATHที่ใดก็ได้ใน

Get-Command eventvwr

CommandType   Name          Definition
-----------   ----          ----------
Application   eventvwr.exe  c:\windows\system32\eventvwr.exe
Application   eventvwr.msc  c:\windows\system32\eventvwr.msc

นอกจากนี้ยังพบว่า cmdlets PowerShell ฟังก์ชั่นชื่อแทนไฟล์ที่มีนามสกุล executables กำหนดเองผ่านทาง$Env:PATHEXTฯลฯ กำหนดไว้สำหรับเปลือกปัจจุบัน (ค่อนข้างคล้ายกับการทุบตีของtype -a foo) - ทำให้ดีขึ้นไปสู่กว่าเครื่องมืออื่น ๆ เช่นwhere.exe, which.exeฯลฯ ซึ่งไม่รู้จักเหล่านี้ คำสั่ง PowerShell

การค้นหาไฟล์ที่เรียกทำงานได้โดยใช้เพียงบางส่วนของชื่อ

gcm *disk*

CommandType     Name                             Version    Source
-----------     ----                             -------    ------
Alias           Disable-PhysicalDiskIndication   2.0.0.0    Storage
Alias           Enable-PhysicalDiskIndication    2.0.0.0    Storage
Function        Add-PhysicalDisk                 2.0.0.0    Storage
Function        Add-VirtualDiskToMaskingSet      2.0.0.0    Storage
Function        Clear-Disk                       2.0.0.0    Storage
Cmdlet          Get-PmemDisk                     1.0.0.0    PersistentMemory
Cmdlet          New-PmemDisk                     1.0.0.0    PersistentMemory
Cmdlet          Remove-PmemDisk                  1.0.0.0    PersistentMemory
Application     diskmgmt.msc                     0.0.0.0    C:\WINDOWS\system32\diskmgmt.msc
Application     diskpart.exe                     10.0.17... C:\WINDOWS\system32\diskpart.exe
Application     diskperf.exe                     10.0.17... C:\WINDOWS\system32\diskperf.exe
Application     diskraid.exe                     10.0.17... C:\WINDOWS\system32\diskraid.exe
...

ค้นหาไฟล์ที่กำหนดเองได้

เพื่อหาข้อมูลที่ไม่ใช่หน้าต่าง executables อื่น ๆ (หลาม, ทับทิม, Perl, ฯลฯ ) ส่วนขยายของแฟ้มสำหรับ executables เหล่านั้นจะต้องมีการเพิ่มให้กับPATHEXTตัวแปรด้านสิ่งแวดล้อม (ค่าเริ่มต้น.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.CPL ) เพื่อระบุไฟล์ที่มีนามสกุลเหล่านี้ในPATHไฟล์ปฏิบัติการ ขณะที่Get-Commandยังได้รับเกียรตินิยมตัวแปรนี้จะสามารถขยายเพื่อ executables กำหนดเองรายการ เช่น

$Env:PATHEXT="$Env:PATHEXT;.dll;.ps1;.psm1;.py"     # temporary assignment, only for this shell's process

gcm user32,kernel32,*WASM*,*http*py

CommandType     Name                        Version    Source
-----------     ----                        -------    ------
ExternalScript  Invoke-WASMProfiler.ps1                C:\WINDOWS\System32\WindowsPowerShell\v1.0\Invoke-WASMProfiler.ps1
Application     http-server.py              0.0.0.0    C:\Users\ME\AppData\Local\Microsoft\WindowsApps\http-server.py
Application     kernel32.dll                10.0.17... C:\WINDOWS\system32\kernel32.dll
Application     user32.dll                  10.0.17... C:\WINDOWS\system32\user32.dll

คุณสามารถตั้งค่านามแฝงได้อย่างรวดเร็วด้วยsal which gcm(รูปแบบสั้น ๆset-alias which get-command)

Get-Commandข้อมูลเพิ่มเติมและตัวอย่างสามารถพบได้ภายใต้ความช่วยเหลือออนไลน์


2
พบมากกว่าไฟล์ปฏิบัติการ นอกจากนี้ยังจับไฟล์คำสั่ง
Maximilian Burszley

2
@ TheIncorrential1 - ถ้าคุณหมายถึงไฟล์คำสั่งเช่นแบตช์ไฟล์ (.BAT , .CMDฯลฯ ) พวกเขาจะถูกพิจารณาว่าสามารถทำงานได้เพราะส่วนขยายของพวกเขาถูกตั้งชื่อในPATHEXTตัวแปร (ซึ่งโดยค่าเริ่มต้นคือPATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.CPL) ประเภทที่ปฏิบัติการได้อื่น ๆ (เช่น.py, .rbฯลฯ ) สามารถเพิ่มได้โดยการเพิ่มนามสกุลไฟล์ในและสร้างการเชื่อมโยงที่ปฏิบัติการได้ด้วยassoc/ ftype- เช่นdocs.python.org/3.3/using/…
shalomb


40

หากคุณมีการติดตั้ง PowerShell (ซึ่งฉันแนะนำ) คุณสามารถใช้คำสั่งต่อไปนี้ในรูปแบบคร่าว ๆ (แทนที่ชื่อโปรแกรมแทนชื่อไฟล์ที่เรียกใช้งานได้):

($Env:Path).Split(";") | Get-ChildItem -filter programName*

เพิ่มเติมได้ที่นี่: My Manwich ของฉัน! PowerShell ไหน


1
ฉันกำลังมองหาคำสั่ง pithy powershell ที่แน่นอนนี้ ฉันใช้ where.exe แต่ต้องยุ่งกับรหัสข้อผิดพลาดที่ด้านบนของการแยกวิเคราะห์ผลลัพธ์ของมันอยู่ไกลกว่าการแก้ปัญหา powerhell ดั้งเดิม ขอบคุณ!
scobi

9
แต่($Env:Path).Split(";") | Get-ChildItem -filter programName*มันเป็นเรื่องง่ายมากที่จะพิมพ์ ... ;-)
Craig

สิ่งนี้ก็ล้มเหลวเช่นกันหากคุณมีตัวแปรในเส้นทางของคุณซึ่งปกติได้รับการแก้ไขโดยระบบ (aka% JAVA_HOME%)
dragon788

ฉันไม่สามารถใช้งาน exe ได้ฉันพยายามทำสิ่งนี้และใช้งานได้
Asfand Qazi



17

Cygwinเป็นวิธีแก้ปัญหา หากคุณไม่สนใจการใช้โซลูชันของบุคคลที่สาม Cygwin จะเป็นหนทางไป

Cygwin มอบความสะดวกสบายให้กับ * nix ในสภาพแวดล้อม Windows (และคุณสามารถใช้มันในเชลล์คำสั่ง Windows ของคุณหรือใช้เชลล์ * nix ที่คุณต้องการ) มันทำให้คุณมีพื้นที่ทั้งหมดของคำสั่งห้าม * (ชอบwhich) สำหรับ Windows PATHและคุณก็สามารถรวมไดเรกทอรีในการที่คุณ


10
GnuWin32 กล่าวก่อนหน้านี้โดย Ferruccio จะดีกว่ามากในกรณีนี้เท่าที่คุณสามารถมีพื้นเมืองที่ปฏิบัติการอยู่คนเดียว
Piotr Dobrogost

GnuWin32 ยอดเยี่ยมและฉันใช้มัน แต่ถ้าคุณต้องการฟังก์ชั่นนี้โดยไม่ต้องติดตั้งเครื่องมือ GnuWin32 โดยที่ exe ดูเหมือนว่าจะเป็นการโทรที่ถูกต้อง แม้ว่าฉันจะใส่เครื่องมือ GnuWin32 ไว้ใน \ bin $ แชร์บนเครือข่ายของเราเพื่อให้ฉันสามารถใช้พวกเขาจากเวิร์กสเตชัน (และในไฟล์แบตช์) ที่ไม่มีการติดตั้งในเครื่อง
Craig

1
เมื่อเราพูดถึงการใช้ Cygwin ใน Windows ฉันชอบ: cygpath -w "` ซึ่ง <appname> `"
mpasko256

12

ใน PowerShell คือgcmซึ่งให้ข้อมูลที่จัดรูปแบบเกี่ยวกับคำสั่งอื่น ๆ หากคุณต้องการดึงเฉพาะพา ธ ที่สามารถเรียกใช้งานได้ให้ใช้.Sourceหากคุณต้องการที่จะดึงเส้นทางเดียวที่จะปฏิบัติการใช้

ตัวอย่างเช่น: gcm gitหรือ(gcm git).Source

tidbits:

  • พร้อมใช้งานสำหรับ Windows XP
  • มีให้ตั้งแต่ PowerShell 1.0
  • gcmเป็นนามแฝงของGet-Commandcmdlet cmdlet
  • โดยไม่มีพารามิเตอร์ใด ๆ มันจะแสดงรายการคำสั่งทั้งหมดที่มีให้โดยเชลล์โฮสต์
  • คุณสามารถสร้างนามแฝงที่กำหนดเองด้วยSet-Alias which gcmและใช้เช่น:(which git).Sourceและใช้งานได้เช่น:
  • เอกสารอย่างเป็นทางการ: https://technet.microsoft.com/en-us/library/ee176842.aspx

11

ฉันมีฟังก์ชั่นในโปรไฟล์ PowerShell ของฉันชื่อ 'ซึ่ง'

function which {
    get-command $args[0]| format-list
}

นี่คือลักษณะของผลลัพธ์:

PS C:\Users\fez> which python


Name            : python.exe
CommandType     : Application
Definition      : C:\Python27\python.exe
Extension       : .exe
Path            : C:\Python27\python.exe
FileVersionInfo : File:             C:\Python27\python.exe
                  InternalName:
                  OriginalFilename:
                  FileVersion:
                  FileDescription:
                  Product:
                  ProductVersion:
                  Debug:            False
                  Patched:          False
                  PreRelease:       False
                  PrivateBuild:     False
                  SpecialBuild:     False
                  Language:

ไม่มีวิธีแก้ปัญหาอื่นสำหรับฉัน แต่> get-command app.exe | format-listทำงานได้อย่างสมบูรณ์แบบ!
Alexander McFarlane

10

รับ unxutils จากที่นี่: http://sourceforge.net/projects/unxutils/

ทองบนแพลตฟอร์ม windows ทำให้ยูทิลิตี้ยูนิกซ์ที่ดีทั้งหมดบน windows DOS มาตรฐาน รับใช้มานานหลายปี

มันมี 'ซึ่ง' รวมอยู่ด้วย โปรดทราบว่ามันเป็นกรณี ๆ

หมายเหตุ: เพื่อติดตั้งมันจะระเบิด zip ที่ใดที่หนึ่งแล้วเพิ่ม ... \ UnxUtils \ usr \ local \ wbin \ ไปยังตัวแปร env ของระบบพา ธ


2
มันไม่ได้ตรงตามตัวพิมพ์ใหญ่ - เล็กและฉันต้องบอกว่า java.exe ใดแทนที่ java - windows 7
Kalpesh Soni

มันมีคู่ของความผิดหวังแม้ว่าต้องทำอย่างไรกับการขึ้นบรรทัดใหม่นั้น ตัวอย่างเช่น grep จะไม่ตรงกับ EOL หากคุณไม่ใส่ a .สำหรับ \ r มันเป็นวิธีการแก้ปัญหา 99% แต่แน่นอน!
dash-tom-bang

ใช่มันไม่ได้ตรงตามตัวพิมพ์ใหญ่ - เล็ก แต่โดยชื่อไฟล์เริ่มต้นใน Windows จะไม่ตรงตามตัวพิมพ์ใหญ่ - เล็ก
Wernfried Domscheit

8

ไม่ได้อยู่ในสต็อกของ Windows แต่ก็มีให้โดยบริการสำหรับ Unixและมีหลายสคริปต์ง่ายชุดลอยรอบที่ประสบความสำเร็จในสิ่งเดียวกันเช่นนี้อย่างใดอย่างหนึ่ง


1
ยกเว้นว่าคำสั่งที่คุณลิงก์จะแสดงผลลัพธ์ตัวแปร PATH เท่านั้นและไม่ได้ตรวจสอบว่าพบไฟล์ดังกล่าวหรือไม่
Angel O'Sphere

8

หากคุณสามารถหาคอมไพเลอร์ Pascal ฟรีคุณสามารถรวบรวมได้ อย่างน้อยก็ใช้งานได้และแสดงอัลกอริทึมที่จำเป็น

program Whence (input, output);
  Uses Dos, my_funk;
  Const program_version = '1.00';
        program_date    = '17 March 1994';
  VAR   path_str          : string;
        command_name      : NameStr;
        command_extension : ExtStr;
        command_directory : DirStr;
        search_dir        : DirStr;
        result            : DirStr;


  procedure Check_for (file_name : string);
    { Check existence of the passed parameter. If exists, then state so   }
    { and exit.                                                           }
  begin
    if Fsearch(file_name, '') <> '' then
    begin
      WriteLn('DOS command = ', Fexpand(file_name));
      Halt(0);    { structured ? whaddayamean structured ? }
    end;
  end;

  function Get_next_dir : DirStr;
    { Returns the next directory from the path variable, truncating the   }
    { variable every time. Implicit input (but not passed as parameter)   }
    { is, therefore, path_str                                             }
    var  semic_pos : Byte;

  begin
      semic_pos := Pos(';', path_str);
      if (semic_pos = 0) then
      begin
        Get_next_dir := '';
        Exit;
      end;

      result := Copy(Path_str, 1, (semic_pos - 1));  { return result   }
      { Hmm! although *I* never reference a Root drive (my directory tree) }
      { is 1/2 way structured), some network logon software which I run    }
      { does (it adds Z:\ to the path). This means that I have to allow    }
      { path entries with & without a terminating backslash. I'll delete   }
      { anysuch here since I always add one in the main program below.     }
      if (Copy(result, (Length(result)), 1) = '\') then
         Delete(result, Length(result), 1);

      path_str := Copy(path_str,(semic_pos + 1),
                       (length(path_str) - semic_pos));
      Get_next_dir := result;
  end;  { Of function get_next_dir }

begin
  { The following is a kludge which makes the function Get_next_dir easier  }
  { to implement. By appending a semi-colon to the end of the path         }
  { Get_next_dir doesn't need to handle the special case of the last entry }
  { which normally doesn't have a semic afterwards. It may be a kludge,    }
  { but it's a documented kludge (you might even call it a refinement).    }
  path_str := GetEnv('Path') + ';';

  if (paramCount = 0) then
  begin
    WriteLn('Whence: V', program_version, ' from ', program_date);
    Writeln;
    WriteLn('Usage: WHENCE command[.extension]');
    WriteLn;
    WriteLn('Whence is a ''find file''type utility witha difference');
    Writeln('There are are already more than enough of those :-)');
    Write  ('Use Whence when you''re not sure where a command which you ');
    WriteLn('want to invoke');
    WriteLn('actually resides.');
    Write  ('If you intend to invoke the command with an extension e.g ');
    Writeln('"my_cmd.exe param"');
    Write  ('then invoke Whence with the same extension e.g ');
    WriteLn('"Whence my_cmd.exe"');
    Write  ('otherwise a simple "Whence my_cmd" will suffice; Whence will ');
    Write  ('then search the current directory and each directory in the ');
    Write  ('for My_cmd.com, then My_cmd.exe and lastly for my_cmd.bat, ');
    Write  ('just as DOS does');
    Halt(0);
  end;

  Fsplit(paramStr(1), command_directory, command_name, command_extension);
  if (command_directory <> '') then
  begin
WriteLn('directory detected *', command_directory, '*');
    Halt(0);
  end;

  if (command_extension <> '') then
  begin
    path_str := Fsearch(paramstr(1), '');    { Current directory }
    if   (path_str <> '') then WriteLn('Dos command = "', Fexpand(path_str), '"')
    else
    begin
      path_str := Fsearch(paramstr(1), GetEnv('path'));
      if (path_str <> '') then WriteLn('Dos command = "', Fexpand(path_str), '"')
                          else Writeln('command not found in path.');
    end;
  end
  else
  begin
    { O.K, the way it works, DOS looks for a command firstly in the current  }
    { directory, then in each directory in the Path. If no extension is      }
    { given and several commands of the same name exist, then .COM has       }
    { priority over .EXE, has priority over .BAT                             }

    Check_for(paramstr(1) + '.com');     { won't return if file is found }
    Check_for(paramstr(1) + '.exe');
    Check_for(paramstr(1) + '.bat');

    { Not in current directory, search through path ... }

    search_dir := Get_next_dir;

    while (search_dir <> '') do
    begin
       Check_for(search_dir + '\' + paramstr(1) + '.com');
       Check_for(search_dir + '\' + paramstr(1) + '.exe');
       Check_for(search_dir + '\' + paramstr(1) + '.bat');
       search_dir := Get_next_dir;
    end;

    WriteLn('DOS command not found: ', paramstr(1));
  end;
end.

21
ว้าวมีคนยังใช้ Pascal อยู่ไหม? :-)
paxdiablo

6
ฉันคิดว่ามี แต่ไม่ใช่ฉัน. คุณเห็น line line_date = '17 March 1994 ';
Mawg กล่าวว่าคืนสถานะโมนิก้า

1
หน่วยmy_funk;ไม่จำเป็น ขอบคุณสำหรับการโพสต์โปรแกรมภาษาปาสกาลทำให้ฉันนึกถึงวัยรุ่นของฉัน! มันช่างน่าเสียดายที่ Pascal ไม่ได้วิวัฒนาการ
yannis

2
โอ้ แต่มันก็เป็นเช่นนั้น ตอนนี้มันเป็นวัตถุเชิง มีฟรีข้ามแพลตฟอร์มการดำเนินงานและ IDE ที่lazarus-ide.org และผู้สืบทอดโดยตรงของ Borland ยังคงอาศัยอยู่ใน Delphi ที่embarcadero.com/products/delphiซึ่งมีราคาแพงมาก (IMO) ที่ $ 299 สำหรับรุ่นเริ่มต้น และ $ 1k สำหรับรุ่น "ใช้งานได้" อย่างไรก็ตามมันเป็นแพลตฟอร์มข้าม - windows, iOs, Mac, Android รับรุ่นทดลองใช้หรือใช้ Lazarus และรู้สึกอ่อนกว่าวัย 20 ปี -)
Mawg พูดว่าคืนสถานะโมนิก้า

1
@ yannis "น่าเสียดายที่ Pascal ไม่ได้วิวัฒนาการ" ... นอกเหนือจาก 'Turbo Pascal' Anders กำลังออกแบบ C # คุณหมายความว่าอย่างไร?
piers7

7

รุ่นที่ดีที่สุดที่ฉันพบบน Windows คือยูทิลิตี้ "whereis" ของ Joseph Newcomer ซึ่งมีอยู่ (พร้อมแหล่งที่มา) จากเว็บไซต์ของเขาเว็บไซต์ของเขา

บทความเกี่ยวกับการพัฒนา "whereis" มีค่าอ่าน


1
ความคิดเห็นล่าช้า: whereis มีปัญหาในการค้นหา executables 64- บิตภายใต้ Win 7 64- บิต
Axel Kemper


6

ไม่มีพอร์ต Win32 ของ Unix ที่ฉันสามารถหาได้บนอินเทอร์เน็ตเป็น satistactory เพราะพวกเขาทั้งหมดมีข้อบกพร่องเหล่านี้อย่างน้อยหนึ่งอย่าง:

  • ไม่รองรับตัวแปร Windows PATHEXT (ซึ่งกำหนดรายการของส่วนขยายที่ถูกเพิ่มเข้าไปในแต่ละคำสั่งโดยปริยายก่อนที่จะสแกนเส้นทางและตามลำดับ) (ฉันใช้สคริปต์ tcl จำนวนมากและไม่มีเครื่องมือสาธารณะใดที่สามารถค้นหาได้)
  • ไม่รองรับหน้ารหัส cmd.exe ซึ่งทำให้พวกเขาแสดงเส้นทางที่มีอักขระที่ไม่ใช่ ASCII ไม่ถูกต้อง (ฉันอ่อนไหวมากกับเรื่องนั้นด้วยçในชื่อของฉัน :-))
  • ไม่รองรับกฎการค้นหาที่แตกต่างกันใน cmd.exe และบรรทัดคำสั่ง PowerShell (ไม่มีเครื่องมือที่เปิดเผยต่อสาธารณชนจะพบสคริปต์. ps1 ในหน้าต่าง PowerShell แต่ไม่พบในหน้าต่าง cmd!)

ดังนั้นในที่สุดฉันก็เลยเขียนของตัวเองซึ่งนั่นทำให้ทุกอย่างถูกต้อง

มีให้ที่นั่น: http://jf.larvoire.free.fr/progs/which.exe


FYI ผมเคยเปิดมาเครื่องมือ which.exe ของฉันดังกล่าวข้างต้นและอื่น ๆ อีกมากมายในgithub.com/JFLarvoire/SysToolsLib คุณอาจได้รับรุ่นล่าสุดรายงานปัญหา ฯลฯ
Jean-François Larvoire

6

ไฟล์ชุดนี้ใช้การจัดการตัวแปร CMD เพื่อค้นหาคำสั่งที่จะดำเนินการในเส้นทาง หมายเหตุ: ไดเรกทอรีปัจจุบันจะทำก่อนเส้นทาง) และขึ้นอยู่กับการเรียก API ที่ใช้ตำแหน่งอื่นจะค้นหาก่อน / หลังเส้นทาง

@echo off
echo. 
echo PathFind - Finds the first file in in a path
echo ======== = ===== === ===== ==== == == = ====
echo. 
echo Searching for %1 in %path%
echo. 
set a=%~$PATH:1
If "%a%"=="" (Echo %1 not found) else (echo %1 found at %a%)

ดูset /?เพื่อขอความช่วยเหลือ


6

ฉันใช้ GOW (GNU บน Windows) ซึ่งเป็น Cygwin รุ่นเล็ก คุณสามารถคว้าได้จาก GitHub ที่นี่

GOW (GNU บน Windows) เป็นทางเลือกที่มีน้ำหนักเบาสำหรับ Cygwin จะใช้ตัวติดตั้ง Windows ที่สะดวกสบายซึ่งติดตั้งแอปพลิเคชั่น UNIX โอเพนซอร์สที่มีประโยชน์อย่างมากประมาณ 130 แอปซึ่งรวบรวมเป็นไบนารีเนติบัณฑิตยของ win32 มันถูกออกแบบให้มีขนาดเล็กที่สุดเท่าที่เป็นไปได้ประมาณ 10 MB ซึ่งตรงข้ามกับ Cygwin ซึ่งสามารถทำงานได้ดีกว่า 100 MB ขึ้นอยู่กับตัวเลือก - เกี่ยวกับคำอธิบาย (Brent R. Matzelle)

สกรีนช็อตของรายการคำสั่งที่รวมอยู่ใน GOW:

ป้อนคำอธิบายภาพที่นี่


5

ฉันได้สร้างเครื่องมือคล้ายกับ Ned Batchelder:

กำลังค้นหาไฟล์. dll และ. exe ใน PATH

ในขณะที่เครื่องมือของฉันใช้สำหรับค้นหา dll รุ่นต่าง ๆ เป็นหลักจะแสดงข้อมูลเพิ่มเติม (วันที่ขนาดรุ่น) แต่ไม่ใช้ PATHEXT (ฉันหวังว่าจะอัปเดตเครื่องมือของฉันเร็ว ๆ นี้)


5

เพียงแค่ต้องโพสต์ไฟล์ชุดซับหนึ่งของ Windows นี้:

C:>type wh.cmd
@for %%f in (%*) do for %%e in (%PATHEXT% .dll .lnk) do for %%b in (%%f%%e) do for %%d in (%PATH%) do if exist %%d\%%b echo %%d\%%b

การทดสอบ:

C:>wh ssh
C:\cygwin64\bin\ssh.EXE
C:\Windows\System32\OpenSSH\\ssh.EXE

ไม่มากหนึ่งซับถ้าคุณตัดรหัสในและsetlocal enableextensionsendlocal


2
อยากให้เป็นแบบหลายบรรทัดเพื่อให้ฉันสามารถเข้าใจได้ ;-)
Gringo Suave

4

สำหรับคุณผู้ใช้ Windows XP (ที่ไม่มีwhereคำสั่งในตัว) ผมได้เขียน "ที่ชอบ" คำสั่งเป็น RubyGem whichrที่เรียกว่า

หากต้องการติดตั้งให้ติดตั้ง Ruby

แล้วก็

gem install whichr

เรียกใช้เช่น:

C:> อันไหน cmd_here


3
ฉันสงสัยว่าคุณถูกลดระดับลงเพราะคุณแนะนำให้ทำสิ่งใดใน Windows XP
sebastian-c

1
ไม่ได้ลงคะแนนเลย แต่การติดตั้ง Ruby เพื่อใช้คำสั่งที่ไม่สำคัญก็เป็นการขายที่ยากเช่นกัน มีการวนรอบด้านบนที่สามารถใส่ลงในชุดสคริปต์
Gringo Suave

2
มันพิมพ์บรรทัดเปิดให้เพลงธีมสำหรับThe Witcher หรือไม่ถ้าคุณใช้มันในโหมด verbose? ;)
Agi Hammerthief

3

TCC และ TCC / LE จาก JPSoft คือการเปลี่ยน CMD.EXE ที่เพิ่มฟังก์ชันการทำงานที่สำคัญ เกี่ยวข้องกับคำถามของ OP whichคือคำสั่ง builtin สำหรับตัวประมวลผลคำสั่งตระกูล TCC


2

ฉันใช้whichโมดูลตั้งแต่เวลา 23.00 น. และใช้งานได้ดี: https://www.npmjs.com/package/which มันเป็นทางเลือกที่ยอดเยี่ยมสำหรับหลายแพลตฟอร์ม

ตอนนี้ฉันเปลี่ยนเป็นสิ่งwhichที่มาพร้อมกับ Git เพียงแค่เพิ่มไปยังเส้นทางของคุณ/usr/binเส้นทางจาก Git C:\Program Files\Git\usr\bin\which.exeซึ่งเป็นปกติจะอยู่ที่ ไบนารีจะเป็นที่which C:\Program Files\Git\usr\bin\which.exeมันเร็วกว่าและใช้งานได้ตามที่คาดไว้


1

ลองนี้

set a=%~$dir:1
If "%for%"=="" (Echo %1 not found) else (echo %1 found at %a%)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.