Bash의 내장 명령을 추적하는 것이 가능합니까?

Bash의 내장 명령을 추적하는 것이 가능합니까?

이 질문에서 영감을 얻었습니다.내장 명령은 언제 메모리에 로드됩니까?, 이 질문에 답하려고 노력하는 동안 다음 명령을 시도했지만 실행할 수 없다는 사실에 조금 놀랐습니다.

$ strace cd $HOME

Bash의 내장 명령을 얻기 위해 strace를 실행할 수 있는 방법이 있습니까?

답변1

그것이 어떻게 작동하는지 생각해 보면 straceBash의 내장 기능 중 하나라도 추적할 수 없다는 것이 완벽하게 이해됩니다. strace실제 실행 파일만 추적할 수 있으며 내장 함수는 추적할 수 없습니다.

예를 들어 내 cd명령은 다음과 같습니다.

$ type cd
cd is a function
cd () 
{ 
    builtin cd "$@";
    local result=$?;
    __rvm_project_rvmrc;
    __rvm_after_cd;
    return $result
}

CD 추적에 대한 팁?

strace나는 실제 bash프로세스를 호출하고 간접적으로 추적할 수 있는 이 기술을 발견했습니다 cd.

$ stty -echo
$ cat | strace bash > /dev/null

이를 통해 다음과 같이 전체 bash프로세스를 추적할 수 있습니다.

....
getegid()                               = 501
getuid()                                = 500
getgid()                                = 501
access("/bin/bash", X_OK)               = 0
stat("/bin/bash", {st_mode=S_IFREG|0755, st_size=940312, ...}) = 0
geteuid()                               = 500
getegid()                               = 501
getuid()                                = 500
getgid()                                = 501
access("/bin/bash", R_OK)               = 0
getpgrp()                               = 32438
rt_sigaction(SIGCHLD, {0x43e360, [], SA_RESTORER, 0x34e7233140}, {SIG_DFL, [], SA_RESTORER, 0x34e7233140}, 8) = 0
getrlimit(RLIMIT_NPROC, {rlim_cur=1024, rlim_max=62265}) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
fcntl(0, F_GETFL)                       = 0 (flags O_RDONLY)
fstat(0, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
lseek(0, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
read(0, 

이것은 입력을 기다리는 Bash 프롬프트입니다. 그럼 다음과 같이 명령을 내리자 cd ...

read(0, "c", 1)                         = 1
read(0, "d", 1)                         = 1
read(0, " ", 1)                         = 1
read(0, ".", 1)                         = 1
read(0, ".", 1)                         = 1
read(0, "\n", 1)                        = 1
stat("/home", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat("/home/saml", {st_mode=S_IFDIR|0700, st_size=32768, ...}) = 0
stat("/home/saml/tst", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0
stat("/home/saml/tst/90609", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0
stat("/home/saml/tst/90609", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0
chdir("/home/saml/tst")                 = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
read(0, 

위 출력에서 ​​명령을 입력한 cd ..다음 Enter( \n)를 눌렀던 위치를 확인할 수 있습니다. 거기에서 stat()함수가 호출되고 Bash가 다른 read(0..프롬프트에서 다른 명령을 기다리는 것을 볼 수 있습니다 .

답변2

쉘 에 대해 strace다음을 수행하십시오 cd /some/dir.

{ strace -p "$$" & sleep 1; cd /some/dir; kill "$!"; }

답변3

다음을 시도해 볼 수 있습니다.

strace bash -c <command/builtin>

예를 들어:

strace bash -c 'cd /path/to/destination/'

관련 정보