이 질문에서 영감을 얻었습니다.내장 명령은 언제 메모리에 로드됩니까?, 이 질문에 답하려고 노력하는 동안 다음 명령을 시도했지만 실행할 수 없다는 사실에 조금 놀랐습니다.
$ strace cd $HOME
Bash의 내장 명령을 얻기 위해 strace를 실행할 수 있는 방법이 있습니까?
답변1
그것이 어떻게 작동하는지 생각해 보면 strace
Bash의 내장 기능 중 하나라도 추적할 수 없다는 것이 완벽하게 이해됩니다. 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/'