2011-02-24 15 views
5

मुझे एक परियोजना सौंपी गई है जिसमें कई दर्जन (शायद 100 से अधिक, मैंने गिना नहीं है) बैश स्क्रिप्ट शामिल हैं। अधिकांश स्क्रिप्ट स्क्रिप्ट्स में से किसी एक को कम से कम एक कॉल बनाती हैं। मैं कॉल ग्राफ़ के बराबर प्राप्त करना चाहता हूं जहां नोड्स फ़ंक्शंस की बजाय स्क्रिप्ट हैं।शैल स्क्रिप्ट कॉल पेड़ उत्पन्न करें

क्या ऐसा करने के लिए कोई मौजूदा सॉफ्टवेयर है?

यदि नहीं, तो क्या किसी के पास यह करने के लिए चालाक विचार हैं?

स्क्रिप्ट की गणना करने के लिए सबसे अच्छी योजना मैं आ सकती थी और यह देखने के लिए जांच कर रहा था कि बेसनाम अद्वितीय हैं (वे एकाधिक निर्देशिकाएं फैलाते हैं)। यदि डुप्लिकेट बेसनाम हैं, तो रोएं, क्योंकि स्क्रिप्ट पथ आमतौर पर वेरिएबल नामों में होते हैं ताकि आप असंबद्ध नहीं हो सकें। यदि वे अद्वितीय हैं, तो स्क्रिप्ट में नाम grep और ग्राफ का निर्माण करने के लिए उन परिणामों का उपयोग करें। ग्राफ को देखने के लिए कुछ टूल (सुझाव?) का प्रयोग करें।

सुझाव?

+0

Graphviz एक अच्छा दृश्य उपकरण है, लेकिन आप के लिए पहले से प्रक्रिया अपने basename'd उत्पादन किसी तरह की जरूरत है यह Graphviz को पार करने से पहले। आप अपनी स्क्रिप्ट को डीबग करने के लिए bashdb का उपयोग करने का प्रयास कर सकते हैं। – vissi

+0

मैं नियमित रूप से इन दिनों नियमित रूप से क्या करता हूं, निर्भर करता है: प्रत्येक स्क्रिप्ट की शुरुआत में सही टिप्पणी करें। शायद किसी भी बड़े पैमाने पर बाद में विचार करने के लिए संभव नहीं है, लेकिन यह एक बहुत ही सरल सम्मेलन है जिसने मुझे अच्छी तरह से सेवा दी है। – tripleee

उत्तर

1

यहाँ कैसे मैं यह कर समापन (अस्वीकरण: इस का एक बहुत, हैक-ish है तो आप को साफ करने के आप इसे लंबे समय तक उपयोग करने के लिए जा रहे हैं चाहते हो सकता है) है ...

अनुमान : - वर्तमान निर्देशिका में प्रश्न में सभी स्क्रिप्ट/बाइनरी शामिल हैं। - ग्राफ बनाने के लिए फ़ाइलें subdir call_graph में जाती हैं।

स्क्रिप्ट कॉल_ग्राफ/make_tgf बनाया गया।श:

#!/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 

मैं तो yEd में जिसके परिणामस्वरूप TGF फ़ाइल खोला, और YED लेआउट करना था (लेआउट -> पदानुक्रमित)। मैं मैन्युअल रूप से जेनरेट की गई फ़ाइल से मैन्युअल रूप से संपादन योग्य फ़ाइल को अलग करने के लिए ग्राफ़्राम के रूप में सहेजा गया।

मुझे पता चला कि कुछ नोड्स थे जो ग्राफ में होने में सहायक नहीं थे, जैसे उपयोगिता स्क्रिप्ट/बाइनरी जिन्हें पूरे स्थान पर बुलाया गया था। इसलिए, मैंने इन्हें स्रोत/लक्ष्य फ़ाइलों से हटा दिया और जब तक मुझे नोड सेट पसंद नहीं आया तब तक पुन: उत्पन्न किया गया।

आशा इस मदद करता है किसी को ...

+0

मैं yEd सेट करने में सक्षम नहीं हूं। क्या टीजीएफ फाइलों को देखने का कोई विकल्प है? – user13107

3

अपने कार्यान्वयन के द्वारा स्वयं को खोलें, लॉग इन करें जो आपको रैपर कहलाता है और मूल खोल निष्पादित करता है।

हां आपको स्क्रिप्ट को वास्तव में उपयोग करने के लिए स्क्रिप्ट शुरू करना होगा। अन्यथा आपको एक ही ज्ञान के साथ एक उपकरण की आवश्यकता है क्योंकि शेल इंजन स्वयं को पूरे चर विस्तार, पीएटीएच इत्यादि का समर्थन करने के लिए है - मैंने इस तरह के टूल के बारे में कभी नहीं सुना है।

कॉलिंग ग्राफ़ GraphViz के डॉट प्रारूप का उपयोग करने के लिए।

+0

चतुरता के लिए उपवास। शायद मैं अनैतिक हूं लेकिन खोल को लपेटना मेरे लिए कभी नहीं हुआ। दुर्भाग्यवश, इन सभी को चलाने के लिए मेरे लिए व्यावहारिक नहीं है; मैं यह भी नहीं जानता कि उनमें से अधिकतर क्या करते हैं या जो महत्वपूर्ण हैं। मैं मानता हूं कि परिवर्तनीय विस्तार और पथ समस्याएं कठिन हैं, लेकिन मुझे इसे कोड के आधार पर करना है, या इसके बिना बस रहना है। –

+0

ठीक है, यदि आप एक नए कार्यान्वयन के बारे में सोच रहे हैं तो मूल खोल स्रोत (ओपन सोर्स?) लेने के लिए विचार करें और वहां अपना तर्क जोड़ें। आपको कम के लिए पार्सर मिल जाएगा। शैल स्क्रिप्ट को छोड़कर सभी निष्पादन() कॉल को अक्षम करने का प्रयास करें और जो भी आप ढूंढ रहे हैं उसे लॉग करें। क्योंकि मैंने इस तरह के एक परियोजना के बारे में कभी नहीं सुना है, इसलिए मैं आपकी प्रगति के बारे में यहां से दिलचस्प हूं। सौभाग्य। –

0

# के बाद प्रत्येक शेल स्क्रिप्ट की शुरुआत में एक पंक्ति डालें! लाइन, जो एक टाइमस्टैम्प लॉग करता है, स्क्रिप्ट का पूरा पथनाम, और तर्क सूची।

समय के साथ, आप इस लॉग को संभावित उम्मीदवारों की पहचान करने के लिए कर सकते हैं, यानी दो लाइनें बहुत करीब लॉग इन की गई हैं, दूसरी स्क्रिप्ट को कॉल करने वाली पहली स्क्रिप्ट की उच्च संभावना है।

यह आपको उन स्क्रिप्ट पर फ़ोकस करने की अनुमति देता है जो वास्तव में उपयोग में हैं।

तुम बहुत तरह इसे चलाने के लिए एक एड स्क्रिप्ट

1a 
log blah blah blah 
. 
wq 

इस्तेमाल कर सकते हैं और:

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

सुनिश्चित करें कि आप कार्यकारी खंड के बजाय प्रिंट के साथ खोजने के आदेश का परीक्षण करें। और/शायद वह पथ नहीं है जिसका आप उपयोग करना चाहते हैं। यदि आपको बिन निर्देशिकाएं शामिल करनी होंगी तो आपको संभवतः शामिल करने के लिए पथनामों की पहचान करने के लिए grep पर स्विच करने की आवश्यकता होगी, फिर जब आपके पास सही नामों से भरा फ़ाइल हो, तो स्क्रिप्ट चलाने के बजाए xargs का उपयोग करें।

+0

ओह, और आपको एक लॉग स्क्रिप्ट या अधिमानतः एक खोल उपनाम/फ़ंक्शन लिखने की भी आवश्यकता है। –

संबंधित मुद्दे