수정해야 할 스크립트가 많습니다. 각 스크립트는 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 및 스크립트 이름과 같은 정보를 데이터베이스에 씁니다. 이 코드는 모든 스크립트에 공통됩니다. 그런 다음 스크립트를 실행한 후 데이터베이스 정보를 후처리하여 스크립트 간의 호출 관계를 결정합니다.