是否可以跟踪 Bash 的内置命令?

是否可以跟踪 Bash 的内置命令?

受到这个问题的启发,标题为:内置命令什么时候加载到内存中,在尝试回答这个问题时,我尝试了以下命令,但有点惊讶我无法运行它:

$ strace cd $HOME

有没有一种方法可以用来运行 strace 以获取 Bash 的内置命令?

答案1

如果你考虑一下它strace的工作原理,那么 Bash 的任何内置函数都是不可追踪的,这是完全有道理的。strace只能跟踪实际的可执行文件,而内置函数则不能。

例如我的cd命令:

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

strace'ing 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/'

相关内容