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.

Is it possible to write a command which runs my.sh and prints every path sourced or executed by this script recursively - That is, without altering the original code at all? The idea is to verify which files are actually used for a specific execution path, without time-consuming and error-prone manual tracing.

For example:

$ > my.sh cat <<'EOF'
#!/bin/sh
. ./foo.sh
EOF
$ > foo.sh cat <<'EOF'
#!/bin/sh
./bar.sh
EOF
$ > bar.sh cat <<'EOF'
#!/bin/sh
echo bar
EOF
$ chmod u+x my.sh bar.sh
$ magic command
[...]
./my.sh
./foo.sh
./bar.sh
share|improve this question
add comment

1 Answer

This seems to do the trick:

$ strace -fe open ./my.sh 2>&1 >/dev/null | \
grep --only-matching '^\(\[pid\s\+[0-9]*\] \)\?open("[^"]\+' | \
grep --only-matching '".*' | \
cut --characters 2-

In other words, trace the execution and print open calls, swap stdout and stderr, then format the result to strip away irrelevant text.

It does print some library paths as well, which is not really a big issue:

/etc/ld.so.cache
/lib/x86_64-linux-gnu/libc.so.6
./my.sh
./foo.sh
/etc/ld.so.cache
/lib/x86_64-linux-gnu/libc.so.6
./bar.sh

Some remaining questions:

  • Is there some way to reliably distinguish between shell and library paths? The latter seems to be possible since all the library references use the O_CLOEXEC option, while none of the shell references do.
  • Is it possible to distinguish between sourced and executed paths?
  • Are there demonstrable corner cases where this command will fail?
share|improve this answer
    
One minute too early... :-o –  Hauke Laging Apr 24 '13 at 14:49
add comment

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.