Python 跟踪bash调用

Python 跟踪bash调用,python,linux,bash,scripting,Python,Linux,Bash,Scripting,我想要一个脚本/工具,如understand C++(scitools),它为调用以下命令的master bash脚本提供回溯: 其他bash脚本 蟒蛇 爪哇 Perl 让我知道发生了什么 我不需要复杂的图形,一个简单的文本文件就足够了 我能做什么呢?使用set-x或使用bash-x运行脚本将在执行前打印每一行(但在变量替换之后,这可能很有用,但有时也可能很糟糕): 您可以使用strace跟踪脚本对其他脚本或程序的执行情况 您必须像这样运行脚本:strace-q-f-e execve you

我想要一个脚本/工具,如understand C++(scitools),它为调用以下命令的master bash脚本提供回溯:

  • 其他bash脚本
  • 蟒蛇
  • 爪哇
  • Perl
让我知道发生了什么

我不需要复杂的图形,一个简单的文本文件就足够了


我能做什么呢?

使用
set-x
或使用
bash-x
运行脚本将在执行前打印每一行(但在变量替换之后,这可能很有用,但有时也可能很糟糕):

您可以使用strace跟踪脚本对其他脚本或程序的执行情况

您必须像这样运行脚本:strace-q-f-e execve yourscript.sh

这将跟踪对其他可执行文件的所有调用

[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) —
[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 ~]# 
它甚至会跟踪对perl或其他可执行文件的调用

[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) —
[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 ~]# 

如果您刚刚需要bash脚本调用日志,请使用此应用程序

bash_包装器替换bash本身,记录调用bash_包装器并执行原始bash的人。也就是说,它独立于
-x
选项处理嵌套的bash调用


您可以使用GraphViz的点格式修改源代码以获得调用图。

这并不完全是因为这是bash的打印输出。如果有多个调用(bash call bash),我必须手动执行。因为它是一个主脚本,太多的东西被打印出来;正如你所说(@Joachim),这很糟糕。它应该是
set-x
,而不是
+x
。添加
-v
将打印行而不进行扩展。@丹尼斯:谢谢,修复了。我通常使用的是
bash-x
版本,所以我记不清了。
+x
在这两种情况下都会关闭
xtrace
。非常好,简单而且有用。因此,我需要实现一个bash脚本来调用带有strace的master脚本,并将其传输到文件而不是stdout?如果您总是需要跟踪(即使在生产中),您可以编写一个包装器脚本来执行strace并在日志文件中只捕获stderr(strace-q-f-e execve./x.sh 2>/var/log/x.trace)。这样,您将在stdout上获得正常输出,在/var/log/x.trace中获得跟踪。唯一的问题是,如果您的脚本写入stderr,那么也将以x.trace结束。