dlewin
dlewin

Reputation: 1763

tracking bash calls

I'd like a script/tool like understand C++(scitools) that give backtraces for a master bash script that call :

to let me know what happend.

I don't need sophisticated graph, a simple text file is suficient.

What can let me do that?

Upvotes: 2

Views: 558

Answers (3)

LVitya
LVitya

Reputation: 567

If you just neeed bash scripts call log, use this app https://github.com/lvitya/bash_wrapper

bash_wrapper replaces the bash itself, logs who called bash_wrapper and exec the original bash. That is it deals with nested bash calls independently from -x option.

You can modify the source code to obtain call graph using GraphViz's dot format.

Upvotes: 0

Dan Vatca
Dan Vatca

Reputation: 321

You may use strace to track your script's execution of other scripts or programs.

You will have to run your script like: strace -q -f -e execve yourscript.sh.

This will trace all calls made to other executables.

[root@devel ~]# ./x.sh 
x
y
z
[root@devel ~]# cat x.sh 
#!/bin/bash
echo x
./y.sh

[root@devel ~]# cat y.sh 
#!/bin/bash

echo y
./z.sh
[root@devel ~]# cat z.sh 
#!/bin/bash

echo z

[root@devel ~]# strace -q -f -e execve ./x.sh 
execve("./x.sh", ["./x.sh"], [/* 28 vars */]) = 0
x
[pid 19781] execve("./y.sh", ["./y.sh"], [/* 28 vars */]) = 0
y
[pid 19782] execve("./z.sh", ["./z.sh"], [/* 28 vars */]) = 0
z
[pid 19781] --- SIGCHLD (Child exited) @ 0 (0) ---
--- SIGCHLD (Child exited) @ 0 (0) —

It will trace even calls to perl or other executables.

[root@devel ~]# cat x.sh 
#!/bin/bash
echo x
./y.sh
ls >/dev/null 2>&1
[root@devel ~]# cat y.sh 
#!/bin/bash

echo y
perl -e 'print "z\n";'
[root@devel ~]# ./x.sh 
x
y
z
[root@devel ~]# strace -q -f -e execve ./x.sh 
execve("./x.sh", ["./x.sh"], [/* 28 vars */]) = 0
x
[pid 20300] execve("./y.sh", ["./y.sh"], [/* 28 vars */]) = 0
y
[pid 20301] execve("/usr/bin/perl", ["perl", "-e", "print \"z\\n\";"], [/* 28 vars */]) = 0
z
[pid 20300] --- SIGCHLD (Child exited) @ 0 (0) ---
--- SIGCHLD (Child exited) @ 0 (0) ---
[pid 20302] execve("/bin/ls", ["ls"], [/* 28 vars */]) = 0
--- SIGCHLD (Child exited) @ 0 (0) ---
[root@devel ~]# 

Upvotes: 3

Joachim Sauer
Joachim Sauer

Reputation: 308021

Using set -x or running the script using bash -x will print every line before it's executed (but after variable substitution, which can be useful, but can also be nasty, sometimes):

bash -x myScript.sh

Upvotes: 6

Related Questions