有没有办法显示从其他脚本调用的所有脚本?

有没有办法显示从其他脚本调用的所有脚本?

我有大量的脚本需要修改。每个脚本可能调用 5 到 10 个其他脚本,而这些脚本又可能调用其他几个脚本,谁知道这个兔子洞有多深。

有没有办法获取特定脚本调用的脚本列表?

我在想这样的事情:

/home/root/ $ showscripts mytargetscript

输出将类似于:

/home/root/mytargetscript
/home/root/asubscript
/home/root/bsubscript
...

如果我冒犯了 Unix 众神,我会提前进行忏悔。我在 dba.se 上回答了很多问题。

答案1

没有通用的解决方案,因为脚本可以使用无数种方式来调用其他脚本。您可以执行grep可能适用于您的脚本但不适用于一般情况的操作。

这会调用哪些脚本?

$(find / -executable -name "*.sh" -print0 | shuf -z -n 1)

如果您能够实际运行这些脚本,您可以通过两种方式跟踪它们。

set -x

将使您的脚本以扩展形式打印它执行的每个命令。然后,您可以检查这些命令中是否有运行脚本的命令。

strace -ff

过度杀戮,但strace为您提供了进程所做的一切,并且通过选项,-ff它也几乎沿着兔子洞走到了尽头。我说几乎是因为有很多方法可以绕过它。它遵循守护进程吗?

Grep stracefor 调用open()exec*()并过滤它以查找脚本文件,您可能会接近完整的图片[对于您所做的脚本的一次运行 - 不包括仅在其他条件下调用的脚本]。

$ strace -ff ./testscript.sh |& grep 'open.*\.sh"' 
open("./testscript.sh", O_RDONLY)       = 3
[pid 24486] open("./CD-DVD Image erstellen.sh", O_RDONLY) = 3

因此,您可以创造性地提出解决方案,但不要指望一个适合所有情况的解决方案。

答案2

假设所有脚本都位于同一目录中,它们的名称中没有制表符或换行符,并且您在文件中拥有“有趣”脚本的列表scripts.txt,每行一个,并且还假设您的 shell 可以进行<(...)进程替换:

#! /bin/sh
while read -r s; do
    fgrep -o -w -f <(fgrep -v -w "$s" scripts.txt) "$s" /dev/null | \
        sort -u | \
        tr : '\t' >>calls.txt
done <scripts.txt

这会构建一个文件calls.txt。该文件由制表符分隔的对组成script1 script2,描述“script1调用script2”关系。

您需要输入calls.txt以下 Perl 脚本:

#!/usr/bin/env perl
use v5.10;                  
use strict;                 
use warnings;               

use Graph::Directed;        

my $g = Graph::Directed->new;

while (<>) {                
    chomp;                  
    $g->add_edge( split /\t/ );
}                           

for ( sort $g->vertices ) { 
    say "$_: " . join(', ', sort $g->all_successors($_));
}

该脚本根据调用关系构建有向图,然后打印所有顶点的后继(即脚本)。

当然,该脚本需要Perl模块Graph。假设您有该cpanm脚本,您可以通过运行来安装所需的模块cpanm Graph

答案3

给定一个脚本

$ cat the_script
ls
/bin/ls
touch ./xx.xx
ls
/bin/ls
ls
ls
  /bin/ls
ls
    /bin/ls(tabs)

然后

$ cat the_script | grep ^[[:space:]]*\t*\/

产生

/bin/ls
/bin/ls
  /bin/ls
    /bin/ls

因此,如果这些调用从行的乞求处开始(允许空格或制表符),则会显示这些调用

您还可以识别“执行此操作的文件列表”的可执行文件,而不是维护硬编码列表,例如

$ find -type f -perm /u=x,g=x,o=x
./test.sh
./the_script

你可以用管道

答案4

一种可能的方法(未经测试)如下。

摘要:你有很多 shell 脚本,它们都互相调用。你想知道这些脚本之间的调用关系是什么。

我们假设这些脚本都是作为单独的程序调用的,因为 Gilles 告诉我,在这种情况下,被调用的脚本是调用脚本的子进程。

然后在每个脚本中添加一些代码,将进程 ID、父进程 ID 和脚本名称等信息写入数据库。该代码对于所有脚本来说都是通用的。然后在运行脚本后对数据库信息进行后处理,以确定脚本之间的调用关系。

相关内容