Làm thế nào để tìm tập tin trong đó hàm bash được xác định?


33

Tôi không thể tìm ra cách tìm tệp trong đó hàm bash được xác định ( __git_ps1trong trường hợp của tôi).

Tôi đã thử nghiệm với declare, type, which, nhưng không nói với tôi các tập tin nguồn. Tôi đọc ở đâu đó declarecó thể in tên tệp và số dòng, nhưng không được giải thích như thế nào. Các helptrang cho declarekhông nói nó cũng không.

Làm thế nào tôi có thể nhận được thông tin này?


Nếu đường dẫn đến tệp của hàm không được bao gồm $PATH, thì typesẽ không hoạt động. Bạn có thể muốn thử chỉ sử dụng findhoặc locate. locatesẽ nhanh hơn nhiều, vì nó sử dụng cơ sở dữ liệu có sẵn, nhưng nó sẽ không hoạt động nếu lệnh được cài đặt gần đây.
dùng628544

Câu trả lời:


37

Nếu bạn chuẩn bị chạy chức năng, thì bạn có thể lấy thông tin bằng cách sử dụng set -xđể theo dõi thực thi và đặt PS4biến.

  1. Bắt đầu bash với --debuggerhoặc sử dụng khác shopt -s extdebugđể ghi lại thông tin gỡ lỗi thêm.

  2. Đặt PS4, 'dấu nhắc' được in khi theo dõi để hiển thị dòng nguồn.

  3. Bật truy tìm.

  4. sau đó bạn có thể chạy chức năng của mình và với mỗi dòng bạn sẽ nhận được tên tệp của hàm.

  5. sử dụng set +xđể tắt truy tìm.

Vì vậy, trong trường hợp này, bạn sẽ chạy

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

"-x Sau khi mở rộng từng lệnh đơn giản, đối với lệnh, lệnh case, lệnh chọn hoặc số học cho lệnh, hiển thị giá trị mở rộng của PS4, theo sau là lệnh và các đối số mở rộng hoặc danh sách từ liên quan." Tốt đẹp!
l0b0

25

Nếu bạn không sẵn sàng chạy chức năng, bạn vẫn có thể thiết lập gỡ lỗi và lấy thông tin. Các bước là

  1. bắt đầu bash --debuggerhoặc shopt -s extdebugtrước khi chức năng được xác định.
  2. declare -F __git_ps1

và nó sẽ báo cáo nơi chức năng được xác định.

Ưu điểm của phương pháp này so với việc nhìn thấy dấu vết thực thi có chú thích với PS4 là

  • Sản lượng ít hơn rất nhiều
  • Nó trực tiếp trả lời câu hỏi

Ưu điểm của dấu vết thực thi là

  • Xem tất cả các chức năng được gọi cùng một lúc
  • Xem mối quan hệ giữa các hàm được gọi
  • Xem đệ quy

Tôi mạnh mẽ khuyên bạn nên có shopt -s extdebuglúc bắt đầu của cả hai ~/.bashrc~/.bash_profileđể trang trải các khác nhau file được sử dụng trong khác nhau Invocation trường hợp.


1
Nó cũng hoạt động nếu shopt -s extdebugđược gọi sau khi hàm được định nghĩa. Số dòng chú ý có thể bị tắt (một lỗi hiện tại) nếu hàm được khai báo thông qua eval.
Stéphane Chazelas

Tôi đã sau khi hoàn thành sai lầm cho vpnc. Sau khi bash --debuggertôi phải thực sự kích hoạt hoàn thành để xác định chức năng hoàn thành và báo cáo từ đó declare -F _vpnc.
Harald

9

Giải pháp tuyệt vời của @ icarus hoạt động cho các chức năng, miễn là chúng được xác định theo nghĩa đen và không phải là kết quả của một evalnội dung của tệp khác (trong đó tệp có evalsẽ hiển thị dưới dạng nguồn). Nó sẽ không in tệp nguồn của bí danh, vỏ dựng sẵn (như echo) và tệp thực thi (nhị phân hay không) và tôi tin rằng thông tin này không có sẵn nói chung. Một số lệnh có thể in các tệp nguồn của chúng (và thậm chí có thể trung thực về nó), trong quá trình thực thi bình thường hoặc phản hồi tín hiệu.

__git_ps1được định nghĩa trong /usr/share/git/git-prompt.sh/usr/share/git/completion/git-prompt.shtrên hệ thống của tôi, Arch Linux, vì vậy nó có thể giống với bạn.

Hãy xem phần Invocationman bash nếu bạn muốn tìm kiếm các lệnh có nguồn gốc cụ thể khi bắt đầu shell - chúng có thể nguồn các tệp khác lần lượt lấy các tệp khác.


Ai có thể có được một danh sách các tập tin có nguồn gốc khi bắt đầu bash?
pfnuesel

@pfnuesel - tùy bạn. Mặc định là trong $HOME/.bashrcvà trong $HOME/.profile. Xem: linuxfromscratch.org/blfs/view/svn/postlfs/profile.html giải thích một số chi tiết về thời điểm và cách mỗi tệp có nguồn gốc.
Joe

2
@Joe gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html là một tài liệu tham khảo tốt hơn nhiều. /etc/profile, $HOME/.bash_profile, $HOME/.bash_login, Và các nội dung của $ENV$BASH_ENVcần phải được bổ sung vào danh sách của bạn.
icarus

@icarus - Cảm ơn. Đó là một lời giải thích tốt hơn.
Joe

8

Nó dường như không thể có trong bash, nhưng nó là zsh:

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

Câu hỏi chỉ định bash ...
Jeff Schaller

4
@JeffSchaller: Cách rõ ràng để sử dụng câu trả lời này là thiết lập zsh để lấy các tệp giống như bash, sau đó sử dụng nó để tìm định nghĩa. Câu trả lời này không gợi ý chuyển sang zsh, chỉ là nó rõ ràng là một công cụ hữu ích hiểu cú pháp shell tốt hơn các công cụ chung như find/ locate/ grep.
Peter Cordes

Sau đó, tôi sẽ tuyên bố, @PeterCordes, rằng câu trả lời này hiện không làm những gì bạn nói nó nên làm để trả lời Câu hỏi. Tôi không biết nếu zsh thực sự đọc cùng một tệp mà bash làm.
Jeff Schaller

@JeffSchaller: Đồng ý câu trả lời này là cần cải thiện. zsh gần như chắc chắn không đọc các ~/.whatevertệp giống như bash theo mặc định và sẽ chỉ đưa ra câu trả lời hữu ích cho các hàm được xác định trong các vị trí được chia sẻ như trong trường hợp này, không được xác định lại trong ~/.bashrchoặc bất cứ điều gì.
Peter Cordes

-1

Khai báo một hàm có cùng tên và đặt nó càng sớm càng tốt, sau đó kích hoạt chế độ xtrace, đại loại như:

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

Sau đó, khi bạn đăng nhập, bạn sẽ thấy thông tin theo dõi bao gồm tìm nguồn của các tệp. Trong thời điểm này có một nỗ lực khai báo hàm chỉ đọc hiện có, bạn sẽ thấy một thông báo lỗi. Các tập tin có nguồn gốc cuối cùng trước khi nó sẽ chứa khai báo bạn tìm kiếm.

Bạn có thể cần phải đặt điều này trong hồ sơ bash hệ thống. Cũng nhớ hoàn nguyên các thay đổi sau khi tìm ra thủ phạm.


-3

Bạn đã thử điều này?

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

hoặc bất kỳ lệnh nào khác được tìm thấy ở đây:

Làm cách nào để tìm tất cả các tệp chứa văn bản cụ thể trên Linux? | Tràn ngăn xếp

Có vẻ như tôi cần phải giải thích cho bạn nhiều hơn. Câu hỏi của bạn hỏi "" Vì vậy, nếu bạn chạy lệnh sau, nó sẽ trả về tất cả các tệp có hàm bash được xác định.

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

Lập trình BASH - Chức năng | Dự án Tài liệu Linux


1
Liên kết chỉ trả lời là hoàn toàn không khuyến khích. Vui lòng thêm một số lời giải thích.
heemayl
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.