跟踪由Bash脚本调用的已执行程序

fly*_*ire 20 linux bash scripting

脚本行为不端.我需要知道谁调用该脚本,谁调用调用脚本等等,只需要修改行为不当的脚本.

这类似于堆栈跟踪,但我对单个bash脚本中的函数调用的调用堆栈感兴趣.相反,我需要由我的脚本启动的已执行程序/脚本链.

Gia*_*rdi 15

我几天前写的一个简单的脚本......

# FILE       : sctrace.sh
# LICENSE    : GPL v2.0 (only)
# PURPOSE    : print the recursive callers' list for a script
#              (sort of a process backtrace)
# USAGE      : [in a script] source sctrace.sh
#
# TESTED ON  :
# - Linux, x86 32-bit, Bash 3.2.39(1)-release

# REFERENCES:
# [1]: http://tldp.org/LDP/abs/html/internalvariables.html#PROCCID
# [2]: http://linux.die.net/man/5/proc
# [3]: http://linux.about.com/library/cmd/blcmdl1_tac.htm

#! /bin/bash

TRACE=""
CP=$$ # PID of the script itself [1]

while true # safe because "all starts with init..."
do
        CMDLINE=$(cat /proc/$CP/cmdline)
        PP=$(grep PPid /proc/$CP/status | awk '{ print $2; }') # [2]
        TRACE="$TRACE [$CP]:$CMDLINE\n"
        if [ "$CP" == "1" ]; then # we reach 'init' [PID 1] => backtrace end
                break
        fi
        CP=$PP
done
echo "Backtrace of '$0'"
echo -en "$TRACE" | tac | grep -n ":" # using tac to "print in reverse" [3]
Run Code Online (Sandbox Code Playgroud)

......还有一个简单的测试.

测试

我希望你喜欢它.

  • 是的,它使用Linux设施(问题是关于Linux,毕竟),对不起...... (2认同)
  • 这最终成为了我在Mac OS X(和Linux)上的作用:虽然调用者我做了i = $((i + 1))完成了 (2认同)

Mir*_*ici 8

你可以使用Bash Debugger http://bashdb.sourceforge.net/

或者,如前面的评论所述,callerbash内置.请参阅:http://wiki.bash-hackers.org/commands/builtin/caller

i=0; while caller $i ;do ((i++)) ;done
Run Code Online (Sandbox Code Playgroud)

另一种方法是更改​​PS4并启用xtrace:

PS4='+$(date "+%F %T") ${FUNCNAME[0]}() $BASH_SOURCE:${BASH_LINENO[0]}+ '
set -o xtrace    # Comment this line to disable tracing.
Run Code Online (Sandbox Code Playgroud)

  • 我特别喜欢这个:i = 0; 而来电者$ i;做((i ++));完成 (3认同)

Jul*_*ano 7

~$ help caller
caller: caller [EXPR]
    Returns the context of the current subroutine call.

    Without EXPR, returns "$line $filename".  With EXPR,
    returns "$line $subroutine $filename"; this extra information
    can be used to provide a stack trace.

    The value of EXPR indicates how many call frames to go back before the
    current one; the top frame is frame 0.
Run Code Online (Sandbox Code Playgroud)


pax*_*blo 6

既然你说你可以编辑脚本本身,只需输入:

ps -ef >/tmp/bash_stack_trace.$$
Run Code Online (Sandbox Code Playgroud)

在其中,问题发生的地方.

这将在您的tmp目录中创建许多文件,这些文件在发生时显示整个进程列表.

然后,您可以通过检查此输出来确定哪个进程调用了哪个进程.这可以手动完成,也可以通过类似的方式自动完成awk,因为输出是常规的 -​​ 您只需使用这些PIDPPID列来计算您感兴趣的所有进程之间的关系.

您需要密切关注文件,因为每个进程都会有一个文件,因此可能需要对其进行管理.由于这是应该只在调试期间完成的事情,因此大多数时候该行将被注释掉(前面有#),因此不会创建文件.

要清理它们,您可以简单地执行以下操作:

rm /tmp/bash_stack_trace.*
Run Code Online (Sandbox Code Playgroud)