他のスクリプトから呼び出されたすべてのスクリプトを表示する方法はありますか?

他のスクリプトから呼び出されたすべてのスクリプトを表示する方法はありますか?

修正するスクリプトがたくさんあります。各スクリプトは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)

実際にこれらのスクリプトを実行できる場合は、2つの方法で追跡できます。

set -x

スクリプトが実行されるすべてのコマンドが拡張形式で印刷されます。その後、これらのコマンドのいずれかがスクリプトを実行していることを確認できます。

strace -ff

Overkillはstraceすべての進行状況を提供し、オプションを使用する-ffと最後までウサギの穴に降ります。私はそれをバイパスする方法があるので、ほとんどそう言います。デーモンプロセスに従いますか?

Grepを呼び出すかstraceフィルタリングしてスクリプトファイルを見つけると、おそらく[実行中のスクリプトの単一実行に対して - 他の条件でのみ呼び出されるスクリプトを除いて]完全な画像に近づくでしょう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

すべてのスクリプトが同じディレクトリにあり、名前にタブや改行文字がなく、ファイルに「興味深い」スクリプトのリストが1行に1つずつあるとし、scripts.txtシェルで<(...)プロセスを置き換えることができるとします。

#! /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 script2script1通話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

テストされていない1つの可能なアプローチは次のとおりです。

要約:多くのシェルスクリプトがあり、すべて互いに呼び出します。これらのスクリプト間の呼び出し関係が何であるかを知りたいです。

Gillesがこの場合、呼び出されたスクリプトは呼び出しスクリプトの子プロセスであると言ったので、これらのスクリプトはすべて別々のプログラムとして呼び出されると仮定します。

次に、各スクリプトにいくつかのコードを追加して、プロセスID、親プロセスID、スクリプト名などの情報をデータベースに書き込みます。このコードはすべてのスクリプトに共通です。次に、スクリプトを実行した後、データベース情報を後処理して、スクリプト間の呼び出し関係を決定します。

関連情報