Есть ли способ отобразить все сценарии, вызываемые из другого скрипта?

У меня есть большое количество сценариев, которые мне нужно изменить. Каждый скрипт, вероятно, вызывает от 5 до 10 других скриптов, которые, в свою очередь, могут вызывать несколько других скриптов, и кто знает, насколько глубоко работает эта кроличья дыра.

Есть ли способ получить список скриптов, вызываемых определенным скриптом?

Я думаю, что-то вроде:

/home/root/ $ showscripts mytargetscript 

выход будет выглядеть примерно так:

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

Если я оскорбил богов Unix, я предлагаю свою покаяние заранее. Я отвечаю на множество вопросов по dba.se.

Существует не общее решение, поскольку существует множество способов, которыми скрипт мог бы использовать для вызова других скриптов. Вы можете сделать grep который может работать для ваших скриптов, но не в целом.

В каких сценариях этот вызов?

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

Если вы действительно можете запустить эти сценарии, вы можете проследить их двумя способами.

 set -x 

заставит ваш скрипт печатать каждую команду, которую он выполняет в развернутой форме. Затем вы можете проверить эти команды для тех, кто запускает скрипты.

 strace -ff 

Overkill, но strace дает вам все, что делает процесс, и с опцией -ff он следует за кроличьей дырой почти до ее конца. Я говорю почти потому, что есть способы обойти это. Это следует за демонами?

Grep the 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 

Поэтому вы можете проявлять творческий подход к своим решениям, просто не ожидайте того, что подходит для каждой ситуации.

Asusming все сценарии живут в одном каталоге, у них нет указаний или новых строк в их именах, и у вас есть список «интересных» в файле scripts.txt , по одному в каждой строке, а также при условии, что ваша оболочка может сделать <(...) подстановки процесса:

 #! /bin/sh while read -rs; 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 , которые описывают отношения « 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 Module. Предполагая, что у вас есть сценарий cpanm , вы можете установить необходимый модуль, запустив cpanm Graph .

Учитывая сценарий

 $ 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 

и вы могли бы

Один из возможных способов (непроверенный) заключается в следующем.

Резюме: у вас много сценариев оболочки, все называют друг друга. Вы хотите знать, что такое отношения между этими сценариями.

Предположим, что все скрипты вызывается как отдельные программы, так как Жиль говорит мне, что в этом случае вызываемый скрипт является дочерним процессом вызывающего скрипта.

Затем поместите код в каждый скрипт, который записывает информацию, такую ​​как идентификатор процесса, идентификатор родительского процесса и имя сценария в базу данных. Этот код может быть общим для всех скриптов. Затем после обработки информации о базе данных после запуска вашего скрипта (ов), чтобы определить связь между сценариями.