2016-10-11 8 views
5

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

# Not a shebang 
echo Hello 

और यह आदेश: उदाहरण के लिए, इस स्क्रिप्ट दी

LD_PRELOAD=/path/to/preload_me.so ./script.sh 

स्क्रिप्ट पुस्तकालय के बिना चलाता है सब, पर लोड किया जा रहा है जो मैं अपने प्रारंभ की (गैर) प्रभाव के माध्यम से निगरानी कर सकते हैं कोड।

दूसरी ओर, अगर मैं एक कुटिया पंक्ति जोड़ें:

#!/bin/sh 
echo Hello 

... तो पुस्तकालय भरी हुई जब मैं एक ही आदेश के माध्यम से स्क्रिप्ट चलाने है। ऐसा कोई फर्क नहीं पड़ता कि कौन सा दुभाषिया निर्दिष्ट है; निश्चित रूप से मैं /bin/bash या किसी अन्य sh -family खोल का भी उपयोग कर सकता हूं मैंने कोशिश की है।

कोई अंतर क्यों है, और क्या यह सुनिश्चित करने का कोई तरीका है कि किसी दिए गए लाइब्रेरी को दिए गए खोल सरल आदेश से पहले प्रीलोड किया गया हो, आदेश के बावजूद?

(another question जिसका लेखक सवाल विरोध इन मामले में couched किया जा रहा से अनुकूलित।)

उत्तर

6

(संदर्भित अन्य प्रश्न के मेरा उत्तर से अनुकूलित।)

यह समझना महत्वपूर्ण है LD_PRELOAD चर नहीं है कि आवश्यक है ऑपरेटिंग सिस्टम या खोल के लिए विशेष महत्व। इसका अर्थ और प्रभाव है - यदि यह उनके पास है - केवल गतिशील लिंकर के संयोजन के साथ। यदि गतिशील लिंकर व्यस्त नहीं है, तो LD_PRELOAD पर्यावरण में बस एक और चर है। इसी तरह यदि गतिशील लिंकर उस चर को पहचान नहीं लेता है (उदाहरण के लिए ओएस एक्स पर)।

यह समझना भी जरूरी है कि एक आदेश को निष्पादित करते समय जिसका नाम किसी फ़ाइल के अनुरूप होता है जो निष्पादन योग्य प्रारूप में नहीं है लेकिन इसमें एक शेबैंग लाइन है, निर्दिष्ट दुभाषिया निष्पादित किया जाता है, भले ही यह खोल हो। यदि दुभाषिया एक ईएलएफ बाइनरी है, जो गतिशील लिंकर संलग्न करता है। दूसरी तरफ, यदि कोई शेबांग लाइन नहीं है तो bash एक सबहेल वातावरण में फ़ाइल की सामग्री निष्पादित करता है, जिसमें गतिशील लिंकर को शामिल करने की आवश्यकता नहीं होती है; इसके बजाय, खोल सिर्फ कांटेदार। अन्य गोले ऐसा ही कर सकते हैं या नहीं कर सकते हैं।

यह भी पहचानना महत्वपूर्ण है कि ईएलएफ के अलावा निष्पादन योग्य प्रारूप मौजूद हैं। आप आधुनिक ईएलएफ-आधारित प्रणाली पर ऐसी बाइनरी में भागने की संभावना नहीं रखते हैं, लेकिन आपको संभावना से इंकार नहीं करना चाहिए।

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

+2

यह एक अच्छा जवाब है, लेकिन मुझे लगता है कि आपको यह स्पष्ट करना चाहिए कि यह विशेष रूप से 'बाश' (और शायद अन्य गोले ') पर लागू होता है, उदाहरण के लिए ऐसा नहीं लगता है। (यह स्क्रिप्ट निष्पादित करता है, लेकिन प्रीलोड प्रभावी होता है।) सभी पॉजिक्स कहते हैं, "शेल खोज के परिणामस्वरूप पथ के साथ बुलाए गए शेल के बराबर एक कमांड निष्पादित करेगा, जो कि इसके पहले ऑपरेंड के रूप में होता है," जो किसी भी व्यवहार पर लागू हो सकता है। (मेरे सिस्टम पर त्वरित परीक्षण: zsh preloads, ksh नहीं है। आंकड़ा जाओ।) – rici

+0

@rici, उत्तर स्पष्ट रूप से कहता है कि * नई बाह प्रक्रिया निष्पादित करने के बजाय * 'bash' * कांटेदार, लेकिन मैंने फिर भी जोड़ा है एक स्पष्टीकरण। –

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