bash 함수가 정의 된 파일을 찾는 방법은 무엇입니까?


33

bash 함수가 정의 된 파일을 찾는 방법을 알 수 없습니다 ( __git_ps1필자의 경우).

나는 실험 declare, type, which,하지만 아무것도 나에게 소스 파일을 알려줍니다. declare파일 이름과 줄 번호를 인쇄 할 수 있는 곳을 읽었 지만 어떻게 설명하지 않았습니다. 에 대한 help페이지도 declare말하지 않았습니다.

이 정보를 어떻게 얻을 수 있습니까?


함수의 파일의 경로가 포함되어 있지 않은 경우 $PATH, 다음 type작동하지 않습니다. 다음을 사용하여 단지 시도 할 수도 find또는 locate. locate기존 데이터베이스를 사용하기 때문에 훨씬 빠르지 만 명령이 최근에 설치된 경우 작동하지 않습니다.
user628544

답변:


37

함수를 실행할 준비가 된 경우 실행 set -x을 추적하고 PS4변수를 설정 하여 정보를 얻을 수 있습니다 .

  1. 추가 디버깅 정보를 기록 --debugger하거나 사용 shopt -s extdebug하여 bash를 시작하십시오 .

  2. PS4소스 라인을 표시하기 위해 추적 할 때 인쇄되는 '프롬프트'를 설정하십시오 .

  3. 추적을 켭니다.

  4. 그런 다음 함수를 실행할 수 있으며 각 줄마다 함수의 파일 이름을 얻습니다.

  5. set +x추적을 끄는 데 사용 합니다.

따라서이 경우에는

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

"-x 각각의 간단한 명령, 명령, 대소 문자 명령, 선택 명령 또는 명령에 대한 산술을 확장 한 후 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의 훌륭한 솔루션 은 문자 그대로 정의되고 다른 파일의 내용 결과가 아닌 함수에 대해 작동합니다 . 별칭의 소스 파일, 셸 내장 (예 :) 및 실행 파일 (이진 여부)을 인쇄하지 않으며이 정보는 일반적으로 사용할 수 없다고 생각합니다. 일부 명령은 정상적인 실행 과정이나 신호에 대한 응답으로 소스 파일을 인쇄 할 수 있습니다.evalevalecho

__git_ps1에 정의 /usr/share/git/git-prompt.sh/usr/share/git/completion/git-prompt.sh내 시스템, 아치 리눅스에, 그래서 당신을 위해 동일 할 수있다.

상기 봐 가지고 호출의 섹션 man bash특별히 쉘의 시작에 공급 명령의 모양을 원하는 경우를 - 그들은 차례로 소스에서 다른 파일을 다른 파일 소스 수 있습니다.


시작할 때 소스 파일 목록을 얻을 수 있습니까 bash?
pfnuesel

@pfnuesel-그것은 당신에게 달려 있습니다. 기본값은 in $HOME/.bashrc및 in $HOME/.profile입니다. 참조 : linuxfromscratch.org/blfs/view/svn/postlfs/profile.html 각 파일이 공급되는시기와 방법의 세부 사항 중 일부를 설명합니다.
Joe

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-감사합니다. 더 나은 설명입니다.
Joe

8

에서 가능하지 않는 것 bash, 그러나 그것은이다 zsh:

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

질문은 bash를 지정합니다 ...
Jeff Schaller

4
@JeffSchaller :이 답변을 사용하는 확실한 방법은 zsh가 bash와 동일한 파일을 소스로 설정 한 다음이를 사용하여 정의를 찾는 것입니다. 이 답변은 더 일반적인 도구이 좋아보다 쉘 구문을 이해하는 유용한 도구 분명히 그냥 것을 zsh을 전환 제안하지 않습니다 find/ locate/가 grep.
Peter Cordes

그런 다음 @PeterCordes는이 답변이 현재 귀하가 질문에 대답하기 위해해야한다고 말한 것을 수행하지 않는다고 주장합니다. zsh가 기본적으로 bash와 동일한 파일을 읽는지 모르겠습니다.
Jeff Schaller

@ JeffSchaller :이 답변은 개선이 필요하다고 동의했습니다. zsh ~/.whatever는 기본적으로 bash 와 동일한 파일을 거의 읽지 않으며이 경우와 같이 공유 위치에 정의 된 기능에 대해서만 유용한 답변을 제공합니다 ~/.bashrc.
Peter Cordes

-1

이름이 같은 함수를 선언하고 가능한 빨리 읽기 전용으로 설정 한 다음 xtrace 모드를 활성화하십시오.

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

그 후 로그인하면 파일 소싱을 포함한 추적 정보가 표시됩니다. 기존 읽기 전용 함수를 선언하려고 시도하는 중에 오류 메시지가 표시됩니다. 마지막 소스 파일에는 찾고자하는 선언이 포함되어야합니다.

이것을 시스템 bash 프로파일에 넣어야 할 수도 있습니다. 또한 범인을 찾은 후 변경 사항을 되 돌리는 것을 잊지 마십시오.


-3

이것을 시도 했습니까?

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

또는 여기에있는 다른 명령 중 하나 :

Linux에서 특정 텍스트가 포함 된 모든 파일을 찾으려면 어떻게합니까? | 스택 오버플로

더 자세한 설명이 필요한 것 같습니다. 질문에 ""를 묻습니다. 따라서 다음 명령을 실행하면 bash 함수가 정의 된 모든 파일을 반환해야합니다.

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

BASH 프로그래밍-기능 | 리눅스 문서화 프로젝트


1
링크 만 답변을 권장하지 않습니다. 설명을 추가하십시오.
heemayl
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.