รายการไฟล์ / ไบนารีทั้งหมดใน PATH ปัจจุบัน


10

มีวิธี "ใช้ง่าย" ในการรันคำสั่งลักษณะ "ls -la" สำหรับการแสดงรายการไฟล์ทั้งหมด / ไบนารีที่ปฏิบัติการได้ใน PATH ปัจจุบันหรือไม่?

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


คุณยกตัวอย่างได้ไหม มันจะแตกต่างกันls -laอย่างไร
John Siu

"ls -la" / "ls -a" ทำรายการไฟล์ในไดเรกทอรีปัจจุบันของคุณเท่านั้น (pwd) ฉันต้องการแสดงรายการไฟล์ (ปฏิบัติการ) ทั้งหมดในไดเรกทอรีทั้งหมดที่รวมอยู่ใน PATH
sme

คำตอบ:


19
compgen -c # will list all the commands you could run.
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. 

นิสัยดีนี่คือสิ่งที่ฉันกำลังมองหา มันยังรวมถึงไบนารีที่ปฏิบัติการได้ในไดเรกทอรีปัจจุบัน ขอบคุณ
sme

ทำงานได้ดี ... ในทุบตี
Emanuel Berg

มีวิธีการระบุเส้นทางของแต่ละรายการโดยไม่ทำwhich $(compgen -A function -abck)อะไร
h3rrmiller

ฉันไม่พบทางเลือกที่ดีกว่านี้อีก
Nykakin

3

$PATHต่อไปนี้เป็นฟังก์ชั่นที่แสดงรายการเนื้อหาของไดเรกทอรีที่ ถ้าผ่านการขัดแย้งฟังก์ชั่นจะแสดงรายการคำสั่งที่มีชื่อมีข้อโต้แย้งอย่างใดอย่างหนึ่ง อาร์กิวเมนต์ถูกตีความเป็นรูปแบบ glob

shopt -s extglob
lspath () {
  local IFS pattern
  IFS='|'
  pattern="*@($*)*"
  IFS=':'
  for d in $PATH; do
    for x in "$d/"$pattern; do
      [ "$x" = "$d/$pattern" ] || echo "${x##*/}"
    done
  done | sort -u
}

เช่นเดียวกับหลาย ๆ สิ่งนี่เป็นเรื่องง่ายใน zsh

lspath () {
  (($#)) || set ''
  print -lr -- $^path/*$^@*(N:t) | sort -u
}

^ตัวละครในการขยายตัวพารามิเตอร์ทำให้เกิดข้อความที่ตัดแบ่งกับอาร์เรย์ที่จะเพิ่มให้กับแต่ละองค์ประกอบอาร์เรย์เช่นพิมพ์path=(/bin /usr/bin); echo $^path/foo รูปลักษณ์ที่เหมือนดูถูกหนังสือการ์ตูน แต่ในความเป็นจริงตัวอักษรธรรมดา, ตัวแทนพารามิเตอร์พิเศษ(อาร์เรย์ของพารามิเตอร์ตำแหน่ง) การที่มีตัวปรับแต่งและอีกครั้ง เป็นตัวระบุแบบกลมเพื่อให้ได้ส่วนขยายที่ว่างเปล่าหากไม่มีคู่ที่ตรงกันตามด้วยตัวแก้ไขประวัติเพื่อเก็บเฉพาะชื่อเบส ("หาง") ของแต่ละคู่/bin/foo /usr/bin/foo
/*$^@*/*$@^*
(N:t) N t

ความลับเพิ่มเติมหลีกเลี่ยงการโทรจากภายนอก แต่นี่เป็นเพียงความสนใจด้านเครื่องสำอาง:

lspath () {
  (($#)) || set ''
  local names; names=($^path/*$^@*(N:t))
  print -lr -- ${(ou)names}
}

ในความเป็นจริงคุณอาจกำลังมองหาaproposคำสั่งซึ่งค้นหาหน้าคนของคำสั่งที่มีคำอธิบายสั้น ๆ ที่มีคำหลัก ข้อ จำกัด คือการค้นหาเฉพาะคำสั่งที่มี man page


ในฟังก์ชั่น zsh ครั้งที่สอง^ดูเหมือนจะไม่มีผลลัพธ์สำหรับการเรียก "no arguments"? หากคุณวางไว้คุณสามารถแสดงรายการทั้งหมดและยังคงค้นหาคำหลักคำเดียว (แต่ไม่ใช่รายการของคำหลักเหล่านั้น) (Non:t)ดูเหมือนว่าจะพูดได้ว่าเครื่องหมายดอกจันจะขยายตัว? ไม่สามารถหาอันสุดท้าย
Emanuel Berg

@EmanuelBerg ถูกต้องขอบคุณสำหรับการแก้ไข ฉันได้เพิ่มคำอธิบายของสัญญาณรบกวนสาย
Gilles 'ดังนั้นหยุดความชั่วร้าย'

ตกลงเรามาดูกัน: หากไม่มีข้อโต้แย้งคุณตั้งค่า "พวกเขา" เป็นอะไรเพราะสิ่งที่มี (เมื่อไม่มี) ยังคงรบกวนสิ่งที่คุณทำต่อไปหรือไม่ นอกจากนี้ผมไม่เคยเห็นตัวพิมพ์เล็กpathแต่เมื่อฉันทำงานในเปลือกเป็นจริง $ PATH :แต่มีช่องว่างแทน ส่วนที่เหลือเป็นใส :)
เอ็มมานู Berg

@EmanuelBerg ไม่: หากไม่มีข้อโต้แย้งฉันตั้งค่าอาร์เรย์ของข้อโต้แย้งเป็นอาร์เรย์แบบองค์ประกอบเดียวที่มีสตริงว่าง ด้วยวิธีนี้ไม่มีข้อโต้แย้งหมายถึงทุกชื่อที่มีการจับคู่สตริงว่างเปล่าคือทุกชื่อตรงกัน $pathเป็นคุณลักษณะ zsh: เป็นพารามิเตอร์ที่ผูกกันอาร์เรย์ที่มีการอัปเดตโดยอัตโนมัติเมื่อPATHมีการอัปเดตและในทางกลับกัน
Gilles 'ดังนั้นหยุดความชั่วร้าย'

อ้าตอนนี้ฉันเห็นแล้ว! ว้าวนั่นเป็นแหกคอก!
Emanuel Berg

1
function findinpath () { 
   OLDIFS="$IFS" ; 
   IFS="$(printf ':\t\n')" ; 
   for regexp in "$@" ; do 
      for adir in $PATH ; do 
         find "$adir" -perm -111 -a ! -type d -ls 2>/dev/null | grep -i "/[^/]*$regexp"
      done ; 
   done ; 
   IFS="$OLDIFS" ; 
}

ค้นหาเฉพาะที่ตรงกับที่: มีอย่างน้อยหนึ่งชุด "x" (ปฏิบัติการ) บิตและที่ไม่ได้เป็นไดเรกทอรี

และใช้กับรายการ regexp ที่จะพบ:

findinpath awk sed '\.sh$'

regexp "." จะแสดงให้คุณเห็นทุกอย่าง
Olivier Dulac

ด้วย IFS ปกติคุณสามารถค้นหารายการที่ซ้ำกันใน $ PATH ของคุณด้วย:echo $PATH | tr ':' '\n' | sort | uniq -d
Olivier Dulac

1
ฉันลองใช้รหัสสำหรับคำตอบทั้งหมดและนี่เป็นเพียงคำเดียวที่ให้ฉันในสิ่งที่ฉันกำลังมองหา
Chris หน้า

ฉันดีใจที่มันช่วย :)
Olivier Dulac

1
for i in $(echo $PATH | sed -e 's/\:/\ /g'); do find "$i" -perm +rwx -exec echo {} \; 2> /dev/null; done

ก่อนอื่นเราจะสะท้อน$PATHไปที่ sed และแทนที่ ":" ด้วย ""

จากนั้นเราจะค้นหาแต่ละสิ่งเหล่านั้นเพื่อค้นหาไฟล์ที่มี rwx และ echo

2> /dev/nullดังนั้นfindจะไม่พิมพ์ข้อผิดพลาด


3
คุณต้องการ-maxdepth 1และ-type fในการค้นหาของคุณมิฉะนั้นคุณจะพบไดเรกทอรีย่อยและไฟล์ของพวกเขา (ซึ่งการค้นหา PATH จะไม่) นอกจากนี้การทดสอบการอนุญาตของคุณเป็นเรื่องแปลก - ควร+xคิดด้วยหรือไม่?
Derobert

นี้จะไม่จัดการกับกรณีขอบเป็นรายการว่างเปล่าที่ถูกต้องเป็นเช่นเดียวกับ '' ยกตัวอย่างเช่นหรือ:/bin /bin::/usr/binลองเพิ่มs/::/:.:/;s/^:/.:/;s/:$/:./ไปยังsedคำสั่ง
Arcege

ที่จริงแล้วfindสามารถค้นหาเส้นทางได้มากขึ้นดังนั้นคุณสามารถทำได้โดยไม่ต้องวนซ้ำ: find $(echo $PATH | sed -e 's/\:/\ /g') -perm +rwx …แน่นอนชื่อไดเรกทอรีที่มีช่องว่างจะทำให้เสีย แต่การวนซ้ำที่ใช้มีปัญหาเดียวกันอยู่แล้ว
จัดการ

@ การจัดการคุณถูกต้อง ฉันเพิ่มเครื่องหมายคำพูดเพื่อแก้ไขปัญหานั้นในตอนนี้
h3rrmiller

ขออภัยนั่นแก้ปัญหาอะไรไม่ได้เลย ปัญหาคือการแทนที่โคลอนด้วยช่องว่างเพื่อให้แยกคำ เพื่อให้คุณเปลี่ยน“/ บาร์ foo: / Fiz baz” เป็น“/ foo บาร์ / Fiz baz” forแล้วผ่านที่ ดังนั้นforจะวนซ้ำรายการ 4 คำ หากต้องการจัดการคำแยกให้ดีขึ้นให้ตั้งค่าIFSตามที่คุณต้องการ: IFS=':'; find $PATH -perm +rwx ….
จัดการ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.