Bash

是否可以將內置命令跟踪到 Bash?

  • February 14, 2019

受這個問題的啟發,標題為:When are the built-in commands loaded to memory,在嘗試回答這個問題時,我嘗試了以下命令,但有點驚訝於我無法執行它:

$ strace cd $HOME

有沒有一種方法可以用來為 Bash 的內置命令執行 strace?

如果你考慮一下它是如何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 ..然後按輸入鍵 ( \n)。從那裡你可以看到該stat()函式被呼叫,然後 Bash 坐在另一個read(0..提示符處,等待另一個命令。

引用自:https://unix.stackexchange.com/questions/90711