この質問に触発されて、タイトルが付けられました: 組み込みコマンドがメモリに読み込まれるタイミング 、これに答えようとしているときに、次のコマンドを試してみましたが、実行できないことに少し驚いていました:
$ 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
プロセスで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..
_プロンプトに座って、別のコマンドを待機していることがわかります。
strace
シェルにcd /some/dir
:
{ strace -p "$$" & sleep 1; cd /some/dir; kill "$!"; }
以下を試すことができます。
strace bash -c <command/builtin>
例えば:
strace bash -c 'cd /path/to/destination/'