มีหนึ่งซับที่จะแสดงรายการ executables ทั้งหมดจาก $ PATH ในทุบตี
มีหนึ่งซับที่จะแสดงรายการ executables ทั้งหมดจาก $ PATH ในทุบตี
คำตอบ:
นี่ไม่ใช่คำตอบ แต่มันแสดงไบนารีซึ่งเป็นคำสั่งที่คุณสามารถเรียกใช้ได้
compgen -c
(สมมติว่าbash
)
คำสั่งที่มีประโยชน์อื่น ๆ
compgen -a # will list all the aliases you could run.
compgen -b # will list all the built-ins you could run.
compgen -k # will list all the keywords you could run.
compgen -A function # will list all the functions you could run.
compgen -A function -abck # will list all the above in one go.
in
, {
... ) และชื่อแทน
ด้วย zsh:
whence -pm '*'
หรือ:
print -rl -- $commands
(โปรดทราบว่าสำหรับคำสั่งที่ปรากฏในองค์ประกอบมากกว่าหนึ่ง$PATH
รายการคำสั่งนั้นจะแสดงเพียงรายการแรกเท่านั้น)
หากคุณต้องการคำสั่งที่ไม่มีพา ธ เต็มและเรียงลำดับได้ดี:
print -rl -- ${(ko)commands}
(นั่นคือรับคีย์ของอาร์เรย์ที่เชื่อมโยงนั้นแทนค่า)
ใน POSIX เชลล์ใด ๆ โดยไม่ต้องใช้คำสั่งภายนอกใด ๆ (สมมติว่าprintf
สร้างขึ้นหากไม่ถอยกลับไปecho
) ยกเว้นการเรียงลำดับสุดท้ายและสมมติว่าไม่มีชื่อที่เรียกใช้งานได้มีบรรทัดใหม่:
{ set -f; IFS=:; for d in $PATH; do set +f; [ -n "$d" ] || d=.; for f in "$d"/.[!.]* "$d"/..?* "$d"/*; do [ -f "$f" ] && [ -x "$f" ] && printf '%s\n' "${x##*/}"; done; done; } | sort
หากคุณไม่มีส่วนประกอบว่างเปล่าใน$PATH
(ใช้.
แทน) หรือส่วนประกอบที่ขึ้นต้นด้วย-
หรือไม่มีอักขระตัวแทน\[?*
ในส่วนประกอบของ PATH หรือชื่อที่สามารถเรียกทำงานได้และไม่มีไฟล์ที่เริ่มต้นด้วย.
คุณสามารถทำให้สิ่งนี้ง่ายขึ้นเพื่อ:
{ IFS=:; for d in $PATH; do for f in $d/*; do [ -f $f ] && [ -x $f ] && echo ${x##*/}; done; done; } | sort
ใช้ POSIX find
และsed
:
{ IFS=:; set -f; find -H $PATH -prune -type f -perm -100 -print; } | sed 's!.*/!!' | sort
หากคุณยินดีที่จะแสดงรายการไฟล์ที่ไม่สามารถเรียกใช้งานได้หรือไฟล์ที่ไม่ได้เกิดขึ้นบ่อยในพา ธ มีวิธีที่ง่ายกว่ามาก:
{ IFS=:; ls -H $PATH; } | sort
ข้ามไฟล์ dot หากคุณต้องการให้เพิ่มการ-A
ตั้งค่าสถานะls
หากคุณมีหรือตั้งค่า POSIX:ls -aH $PATH | grep -Fxv -e . -e ..
$PATH
มีการตั้งค่าและไม่มีส่วนประกอบที่ว่างเปล่าและส่วนประกอบนั้นดูไม่เหมือนหาภาคแสดง (หรือตัวเลือก ls) บางคนก็จะไม่สนใจไฟล์จุด
yash
และzsh
ในการจำลอง SH)
find
หนึ่ง -prune
จะป้องกันรายการไดเรกทอรี คุณอาจต้องการ-L
แทนที่จะ-H
เป็นตามที่คุณต้องการรวม symlinks (ทั่วไปสำหรับ executables) -perm -100
ไม่รับประกันว่าไฟล์นั้นจะสามารถเรียกใช้งานได้โดยคุณ (และอาจ (ไม่น่าจะ) ยกเว้นไฟล์ที่สามารถเรียกใช้งานได้
ฉันมากับสิ่งนี้:
IFS=':';for i in $PATH; do test -d "$i" && find "$i" -maxdepth 1 -executable -type f -exec basename {} \;; done
แก้ไข : ดูเหมือนว่านี่เป็นคำสั่งเดียวที่ไม่เรียกใช้การแจ้งเตือน SELinux ขณะอ่านไฟล์บางไฟล์ในไดเรกทอรี bin โดยผู้ใช้ apache
for
? IFS=:; find $PATH -maxdepth 1 -executable -type f -printf '%f\n'
$PATH
มีการตั้งค่าและไม่มีอักขระตัวแทนและไม่มีส่วนประกอบว่างเปล่า find
ที่ยังถือว่าการดำเนินงานของกนู
-type f
แทนที่จะเป็น (เฉพาะ GNU) -xtype f
นั่นก็จะละเว้น symlink ที่จะไม่แสดงรายการเนื้อหาของ$PATH
ส่วนประกอบที่ symlink
เกี่ยวกับเรื่องนี้
find ${PATH//:/ } -maxdepth 1 -executable
การแทนที่สตริงใช้กับ Bash
$PATH
มีการตั้งค่าไม่มีอักขระตัวแทนหรืออักขระว่างเปล่าไม่มีส่วนประกอบว่างเปล่า นั่นถือว่า GNU พบเช่นกัน โปรดทราบว่า${var//x/y}
เป็นksh
ไวยากรณ์ (สนับสนุนโดย zsh และ bash) การพูดอย่างเคร่งครัดที่ยังถือว่าส่วนประกอบของ $ PATH นั้นไม่ได้find
แสดงเพรดิเคตเช่นกัน
$PATH
ส่วนประกอบนั้นไม่ใช่ symlink
IFS=:
นั้นแข็งแกร่งกว่าการทดแทนสิ่งนี้ เส้นทางที่มีช่องว่างไม่ใช่เรื่องผิดปกติบน Windows การเชื่อมโยงสัญลักษณ์กันอย่างเป็นธรรม -H
แต่ที่แก้ไขได้อย่างง่ายดายด้วย
หากคุณสามารถเรียกใช้งานไพ ธ อนในเชลล์ของคุณสามารถใช้หนึ่งซับต่อไปนี้ (ยาวขัน):
python -c 'import os;import sys;output = lambda(x) : sys.stdout.write(x + "\n"); paths = os.environ["PATH"].split(":") ; listdir = lambda(p) : os.listdir(p) if os.path.isdir(p) else [ ] ; isfile = lambda(x) : True if os.path.isfile(os.path.join(x[0],x[1])) else False ; isexe = lambda(x) : True if os.access(os.path.join(x[0],x[1]), os.X_OK) else False ; map(output,[ os.path.join(p,f) for p in paths for f in listdir(p) if isfile((p,f)) and isexe((p,f)) ])'
นี่เป็นแบบฝึกหัดสนุก ๆ สำหรับตัวเองเพื่อดูว่าสามารถทำได้โดยใช้รหัสไพ ธ อนหนึ่งบรรทัดโดยไม่ต้องใช้ฟังก์ชัน 'exec' ในรูปแบบที่อ่านได้มากขึ้นและด้วยความคิดเห็นบางรหัสมีลักษณะเช่นนี้:
import os
import sys
# This is just to have a function to output something on the screen.
# I'm using python 2.7 in which 'print' is not a function and cannot
# be used in the 'map' function.
output = lambda(x) : sys.stdout.write(x + "\n")
# Get a list of the components in the PATH environment variable. Will
# abort the program is PATH doesn't exist
paths = os.environ["PATH"].split(":")
# os.listdir raises an error is something is not a path so I'm creating
# a small function that only executes it if 'p' is a directory
listdir = lambda(p) : os.listdir(p) if os.path.isdir(p) else [ ]
# Checks if the path specified by x[0] and x[1] is a file
isfile = lambda(x) : True if os.path.isfile(os.path.join(x[0],x[1])) else False
# Checks if the path specified by x[0] and x[1] has the executable flag set
isexe = lambda(x) : True if os.access(os.path.join(x[0],x[1]), os.X_OK) else False
# Here, I'm using a list comprehension to build a list of all executable files
# in the PATH, and abusing the map function to write every name in the resulting
# list to the screen.
map(output, [ os.path.join(p,f) for p in paths for f in listdir(p) if isfile((p,f)) and isexe((p,f)) ])
#!/usr/bin/env python
import os
from os.path import expanduser, isdir, join, pathsep
def list_executables():
paths = os.environ["PATH"].split(pathsep)
executables = []
for path in filter(isdir, paths):
for file_ in os.listdir(path):
if os.access(join(path, file_), os.X_OK):
executables.append(file_)
return executables