จะค้นหาไฟล์ที่กำหนดฟังก์ชั่น bash ได้อย่างไร?


33

ฉันไม่สามารถหาวิธีค้นหาไฟล์ที่กำหนดฟังก์ชั่น bash ( __git_ps1ในกรณีของฉัน)

ผมทดลองกับdeclare, type, whichแต่ไม่มีอะไรบอกฉันแฟ้มแหล่งที่มา ฉันอ่านบางแห่งที่declareสามารถพิมพ์ชื่อไฟล์และหมายเลขบรรทัดได้ แต่ก็ไม่ได้อธิบายว่าอย่างไร helpหน้าdeclareไม่ได้บอกว่ามันทั้ง

ฉันจะรับข้อมูลนี้ได้อย่างไร?


หากเส้นทางไปยังไฟล์ของฟังก์ชั่นไม่รวมอยู่ใน$PATHนั้นtypeจะไม่ทำงาน คุณอาจต้องการที่จะลองเพียงแค่ใช้หรือ find จะเร็วกว่ามากเนื่องจากใช้ฐานข้อมูลที่มีอยู่ล่วงหน้า แต่จะไม่ทำงานหากคำสั่งถูกติดตั้งเมื่อไม่นานมานี้ locatelocate
user628544

ที่เกี่ยวข้อง: unix.stackexchange.com/q/322459/117549
Jeff Schaller

คำตอบ:


37

หากคุณพร้อมที่จะเรียกใช้ฟังก์ชันคุณสามารถรับข้อมูลโดยใช้set -xเพื่อติดตามการดำเนินการและการตั้งค่าPS4ตัวแปร

  1. เริ่มทุบตีด้วย--debuggerหรือใช้อย่างอื่นshopt -s extdebugเพื่อบันทึกข้อมูลการดีบักเพิ่มเติม

  2. ตั้งค่าPS4'พรอมต์' ที่พิมพ์เมื่อติดตามเพื่อแสดงบรรทัดที่มา

  3. เปิดการติดตาม

  4. จากนั้นคุณสามารถเรียกใช้ฟังก์ชันของคุณและสำหรับแต่ละบรรทัดคุณจะได้รับชื่อไฟล์ของฟังก์ชัน

  5. ใช้set +xเพื่อปิดการติดตาม

ดังนั้นสำหรับกรณีนี้คุณจะทำงาน

bash --debugger
PS4='+ ${BASH_SOURCE[0]} '
set -x ; __git_ps1 ; set +x

"-x หลังจากขยายแต่ละคำสั่งง่าย ๆ สำหรับคำสั่งคำสั่ง case เลือกคำสั่งหรือเลขคณิตสำหรับคำสั่งแสดงค่าที่ขยายของ PS4 ตามด้วยคำสั่งและอาร์กิวเมนต์ที่ขยายหรือรายการคำที่เกี่ยวข้อง" ดี!
l0b0

25

หากคุณไม่ต้องการเรียกใช้ฟังก์ชันคุณยังสามารถตั้งค่าการดีบักและรับข้อมูลได้ ขั้นตอนคือ

  1. เริ่มต้นbash --debuggerหรือshopt -s extdebugก่อนที่ฟังก์ชันจะถูกกำหนด
  2. declare -F __git_ps1

และจะรายงานตำแหน่งที่ฟังก์ชันถูกกำหนด

ข้อดีของวิธีนี้เมื่อเทียบกับการดูการติดตามการดำเนินการข้อเขียนด้วย PS4 คือ

  • ผลผลิตน้อยลงมาก
  • มันตอบคำถามโดยตรง

ข้อดีของการติดตามการดำเนินการคือ

  • ดูฟังก์ชั่นที่เรียกทั้งหมดในครั้งเดียว
  • ดูความสัมพันธ์ระหว่างฟังก์ชั่นที่เรียกว่า
  • ดูการสอบถามซ้ำ

ฉันขอแนะนำอย่างยิ่งให้shopt -s extdebugเริ่มตั้งแต่ทั้งคู่~/.bashrcและ~/.bash_profileเพื่อครอบคลุมไฟล์ต่าง ๆ ที่ใช้ในกรณีการร้องขอที่แตกต่างกัน


1
นอกจากนี้ยังใช้งานได้หากshopt -s extdebugถูกเรียกหลังจากฟังก์ชันถูกกำหนด ระวังหมายเลขบรรทัดอาจจะปิด (ข้อผิดพลาดในปัจจุบัน) evalถ้าฟังก์ชันมีการประกาศผ่าน
Stéphane Chazelas

ฉันหลังจากเสร็จสิ้นการเข้าใจผิดสำหรับ vpnc หลังจากที่ฉันได้ไปจริงเรียกเสร็จสิ้นการที่จะได้รับฟังก์ชั่นที่เสร็จสิ้นตามกำหนดและได้รับมันได้รับรายงานจากbash --debugger declare -F _vpnc
Harald

9

โซลูชันที่ยอดเยี่ยมของ @ icarus ใช้งานได้กับฟังก์ชั่นตราบใดที่มีการกำหนดอย่างแท้จริงและไม่ได้เป็นผลมาจากevalเนื้อหาของไฟล์อื่น (ซึ่งไฟล์ที่มีevalจะปรากฏขึ้นเป็นแหล่งที่มา) มันจะไม่พิมพ์ไฟล์ต้นฉบับของ alias, shell built-in (เช่นecho) และ executables (binary หรือไม่) และฉันเชื่อว่าข้อมูลนี้ไม่สามารถใช้งานได้ทั่วไป คำสั่งบางอย่างอาจพิมพ์ไฟล์ต้นฉบับ (และอาจเป็นจริงเกี่ยวกับมัน) ไม่ว่าจะในการดำเนินการตามปกติหรือการตอบสนองต่อสัญญาณ

__git_ps1ถูกกำหนดใน/usr/share/git/git-prompt.shและ/usr/share/git/completion/git-prompt.shบนระบบของฉัน Arch Linux ดังนั้นมันอาจจะเหมือนกันสำหรับคุณ

ดูที่ส่วนการร้องขอของman bashหากคุณต้องการค้นหาคำสั่งที่มาจากจุดเริ่มต้นของเชลล์โดยเฉพาะ - พวกมันอาจจัดหาไฟล์อื่น ๆ ซึ่งทำให้ไฟล์อื่น ๆ


จะได้รับรายชื่อไฟล์ที่มาเมื่อเริ่มต้นbashหรือไม่
pfnuesel

@pfnuesel - แล้วแต่คุณ ค่าเริ่มต้นอยู่ในและใน$HOME/.bashrc $HOME/.profileโปรดดูที่: linuxfromscratch.org/blfs/view/svn/postlfs/profile.htmlซึ่งจะอธิบายรายละเอียดของเวลาและวิธีที่แต่ละไฟล์มีแหล่งที่มา
โจ

2
@ Joe gnu.org/software/bash/manual/html_node/Bash-Startup-Files.htmlคือการอ้างอิงที่ดีมาก /etc/profile, $HOME/.bash_profile, $HOME/.bash_loginและเนื้อหาของ$ENVและ$BASH_ENVจะต้องมีการเพิ่มรายชื่อของคุณ
รัส

@icarus - ขอบคุณ นั่นคือคำอธิบายที่ดีกว่า
โจ

8

ดูเหมือนจะเป็นไปไม่ได้bashแต่อยู่ในzsh:

$ type __git_ps1
> __git_ps1 is a shell function from /usr/share/git/git-prompt.sh

คำถามที่ไม่ระบุทุบตี ...
เจฟฟ์ Schaller

4
@JeffSchaller: วิธีที่ชัดเจนในการใช้คำตอบนี้คือการตั้งค่า zsh เพื่อหาแหล่งไฟล์เดียวกันกับที่ทุบตีแล้วใช้เพื่อค้นหาคำจำกัดความ คำตอบนี้ไม่ได้บอกเปลี่ยนไปใช้ zsh เพียงแค่ว่ามันเห็นได้ชัดว่าเครื่องมือที่มีประโยชน์ที่เข้าใจไวยากรณ์เปลือกดีกว่าเครื่องมือทั่วไปเช่นfind/ /locate grep
Peter Cordes

ฉันจะเรียกร้องแล้ว @PeterCordes ว่าคำตอบนี้ไม่ได้ทำในสิ่งที่คุณพูดว่าควรทำเพื่อตอบคำถาม ฉันไม่รู้ว่า zsh อ่านไฟล์เดียวกับที่ทุบตีหรือไม่
Jeff Schaller

@JeffSchaller: เห็นด้วยกับคำตอบนี้ต้องการการปรับปรุง zsh แทบจะไม่ได้อ่าน~/.whateverไฟล์เดียวกับ bash โดยค่าเริ่มต้นและจะให้เฉพาะคำตอบที่เป็นประโยชน์สำหรับฟังก์ชั่นที่กำหนดไว้ในสถานที่ที่ใช้ร่วมกันเช่นในกรณีนี้ซึ่งไม่ได้กำหนดใหม่~/.bashrcหรืออะไรก็ตาม
Peter Cordes

-1

ประกาศฟังก์ชั่นที่มีชื่อเดียวกันและตั้งให้อ่านอย่างเร็วที่สุดเท่าที่จะเป็นไปได้จากนั้นเปิดใช้งานโหมด xtrace เช่น:

__git_ps1(){ :;}
readonly -f __git_ps1
set -x

หลังจากนั้นเมื่อคุณเข้าสู่ระบบคุณจะเห็นข้อมูลการติดตามที่มีการจัดหาไฟล์ ในขณะนี้มีความพยายามในการประกาศฟังก์ชันอ่านอย่างเดียวที่มีอยู่คุณจะเห็นข้อความแสดงข้อผิดพลาด ไฟล์ที่มาล่าสุดก่อนที่จะควรมีการประกาศที่คุณมองหา

คุณอาจต้องวางสิ่งนี้ลงในโปรไฟล์ทุบตีระบบ นอกจากนี้อย่าลืมยกเลิกการเปลี่ยนแปลงหลังจากค้นหาผู้กระทำผิด


-3

คุณลองนี่ไหม

grep -rnw '/path/to/somewhere/' -e "pattern" 

หรือคำสั่งอื่น ๆ ที่พบที่นี่:

ฉันจะค้นหาไฟล์ทั้งหมดที่มีข้อความเฉพาะบน Linux ได้อย่างไร | กองล้นมากเกินไป

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

grep -rnw 'Path2Search' -e "#!/bin/bash"

การเขียนโปรแกรม BASH - ฟังก์ชั่น โครงการเอกสารลินุกซ์


1
ลิงก์คำตอบเท่านั้นไม่ได้รับการสนับสนุนอย่างแน่นอน โปรดเพิ่มคำอธิบายบางอย่าง
heemayl
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.