Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Inspired by this question, titled: When are the built-in commands loaded to memory, while attempting to answer this I tried the following command and was a bit surprised that I couldn't run it:

$ strace cd $HOME

Is there a method I can make use of to run strace for the builtin commands to Bash?

share|improve this question
    
Why do you think it's surprising that a strace of not running a program doesn't result in a trace? –  Bananguin Sep 15 '13 at 7:23

2 Answers 2

up vote 4 down vote accepted

If you think about how strace works then it makes total sense that none of the builtins to Bash would be traceable. strace can only trace actual executables, whereas the builtins are not.

For example, my cd command:

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

Trick for strace'ing cd?

I came across this technique where you could invoke strace on the actual bash process and in so doing, indirectly trace cd that way.

Example

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

Which results in me being able to strace the bash process as follows:

....
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, 

This is the Bash prompt, where it's sitting there, waiting for some input. So let's give it the command 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, 

From the above output, you can see where I typed the command, cd .. and hit enter, (\n). From there you can see that the stat() function was called, and that afterwards Bash is sitting at another read(0.. prompt, waiting for another command.

share|improve this answer

To strace the shell doing cd /some/dir:

{ strace -p "$$" & sleep 1; cd /some/dir; kill "$1"; }
share|improve this answer
    
Why the $1 here, for bash, should this not be % or %1? –  Graeme Apr 7 at 10:21

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.