다른 스크립트에서 호출된 모든 스크립트를 표시하는 방법이 있습니까?

다른 스크립트에서 호출된 모든 스크립트를 표시하는 방법이 있습니까?

수정해야 할 스크립트가 많습니다. 각 스크립트는 5~10개의 다른 스크립트를 호출할 수 있으며, 이는 여러 개의 다른 스크립트를 호출할 수 있으며 이 토끼굴이 얼마나 깊은지 아는 사람은 없습니다.

특정 스크립트에서 호출한 스크립트 목록을 얻는 방법이 있나요?

나는 다음과 같은 것을 생각하고 있습니다 :

/home/root/ $ showscripts mytargetscript

출력은 다음과 유사합니다.

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

내가 유닉스 신들을 불쾌하게 했다면, 나는 미리 회개할 것입니다. 나는 dba.se에서 많은 질문에 답변합니다.

답변1

스크립트는 수많은 방법으로 다른 스크립트를 호출할 수 있으므로 보편적인 솔루션은 없습니다. grep스크립트에는 작동하지만 일반적으로는 작동하지 않는 작업을 수행할 수 있습니다 .

이것은 어떤 스크립트를 호출합니까?

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

실제로 이러한 스크립트를 실행할 수 있는 경우 두 가지 방법으로 추적할 수 있습니다.

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

모든 스크립트가 동일한 디렉토리에 있고, 이름에 탭이나 개행 문자가 없으며, 파일에 "흥미로운" 스크립트 목록이 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 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

테스트되지 않은 한 가지 가능한 접근 방식은 다음과 같습니다.

요약: 많은 셸 스크립트가 있으며 모두 서로 호출합니다. 이러한 스크립트 간의 호출 관계가 무엇인지 알고 싶습니다.

Gilles가 이 경우 호출된 스크립트는 호출 스크립트의 하위 프로세스라고 말했기 때문에 이러한 스크립트는 모두 별도의 프로그램으로 호출된다고 가정합니다.

그런 다음 각 스크립트에 일부 코드를 추가하여 프로세스 ID, 상위 프로세스 ID 및 스크립트 이름과 같은 정보를 데이터베이스에 씁니다. 이 코드는 모든 스크립트에 공통됩니다. 그런 다음 스크립트를 실행한 후 데이터베이스 정보를 후처리하여 스크립트 간의 호출 관계를 결정합니다.

관련 정보