Создать дерево вызовов сценария оболочки - PullRequest
6 голосов
/ 24 февраля 2011

Мне передали проект, который состоит из нескольких десятков (вероятно, более 100, я не считал) сценариев bash. Большинство сценариев выполняют по крайней мере один вызов другого сценария. Я хотел бы получить эквивалент графа вызовов, где узлами являются сценарии, а не функции.

Существует ли какое-либо программное обеспечение для этого?

Если нет, есть ли у кого-нибудь умные идеи, как это сделать?

Лучший план, который я мог придумать, - перечислить сценарии и проверить, являются ли базовые имена уникальными (они охватывают несколько каталогов). Если есть повторяющиеся базовые имена, то плачьте, потому что пути сценариев обычно хранятся в именах переменных, поэтому вы не сможете устранить неоднозначность. Если они уникальны, выполните поиск имен в сценариях и используйте эти результаты для построения графика. Используйте какой-нибудь инструмент (предложения?) Для визуализации графика.

Предложения

Ответы [ 3 ]

3 голосов
/ 24 февраля 2011

Оберните оболочку самой вашей реализацией, войдите в систему, кто вызвал вас как обертку, и запустите исходную оболочку.

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

Чтобы визуализировать граф вызовов, используйте GraphViz точечный формат.

2 голосов
/ 29 апреля 2015

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

Допущения: - Текущий каталог содержит все скрипты / исполняемые файлы.- Файлы для построения графика идут в subdir call_graph.

Создан скрипт call_graph / make_tgf.sh:

#!/bin/bash
# Run from dir with scripts and subdir call_graph
# Parameters:
# $1 = sources (default is call_graph/sources.txt)
# $2 = targets (default is call_graph/targets.txt)

SOURCES=$1
if [ "$SOURCES" == "" ]; then SOURCES=call_graph/sources.txt; fi
TARGETS=$2
if [ "$TARGETS" == "" ]; then TARGETS=call_graph/targets.txt; fi

if [ ! -d call_graph ]; then echo "Run from parent dir of call_graph" >&2; exit 1; fi
(
#  cat call_graph/targets.txt
  for file in `cat $SOURCES `
  do
    for target in `grep -v -E '^ *#' $file | grep -o -F -w -f $TARGETS | grep -v -w $file | sort | uniq`
    do echo $file $target
    done
  done
)

Затем я запустил следующее (я завелся делать только скриптыверсия):

cat /dev/null | tee call_graph/sources.txt > call_graph/targets.txt
for file in *
do
  if [ -d "$file" ]; then continue; fi
  echo $file >> call_graph/targets.txt
  if file $file | grep text >/dev/null; then echo $file >> call_graph/sources.txt; fi
done

# For scripts only:
bash call_graph/make_tgf.sh call_graph/sources.txt call_graph/sources.txt > call_graph/scripts.tgf

# For scripts + binaries (binaries will be leaf nodes):
bash call_graph/make_tgf.sh > call_graph/scripts_and_bin.tgf

Затем я открыл получившийся файл tgf в yEd и приказал yEd сделать макет (Layout -> Hierarchical).Я сохранил как graphml, чтобы отделить редактируемый вручную файл от автоматически сгенерированного.

Я обнаружил, что в графе были некоторые узлы, которые не были полезны, такие как служебные скрипты / двоичные файлы, которые вызывалисьповсюду.Итак, я удалил их из файлов источников / целей и обновил по мере необходимости, пока мне не понравился набор узлов.

Надеюсь, это кому-нибудь поможет ...

0 голосов
/ 25 февраля 2011

Вставить строку в начале каждого сценария оболочки, после #! строка, в которой записывается метка времени, полный путь к сценарию и список аргументов.

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

Это также позволяет вам сосредоточиться на сценариях, которые все еще используются.

Вы можете использовать скрипт ed

1a
log blah blah blah
.
wq

и запустите его так:

find / -perm +x -exec ed {} <edscript

Убедитесь, что вы тестировали команду find с параметром -print вместо предложения exec. И /, вероятно, не тот путь, который вы хотите использовать. Если вам нужно включить каталоги bin, вам, вероятно, потребуется переключиться на grep, чтобы определить имена путей для включения, а затем, когда у вас есть файл, полный правильных имен, используйте xargs вместо find для запуска сценария.

...