बाश के निर्यात के बराबर zsh क्या है -f


24

इसलिए मैंने इस्तेमाल करना शुरू कर दिया zsh। मुझे यह सब अच्छा लगता है। यह बहुत अच्छा और धीमा लगता है, और यह तथ्य कि वर्तमान वर्किंग डाइरेक्टरी और वास्तविक कमांड लाइन अलग-अलग लाइनों पर हैं, अच्छा है, लेकिन एक ही समय में, मैं यह देख रहा हूं कि zshयह थोड़ा धीमा हो सकता है bash, खासकर जब टेक्स्ट प्रिंट करना स्क्रीन।

मुझे जो बात सबसे अच्छी लगी, वह यह थी कि zshमेरे द्वारा परिभाषित सभी कार्यों के साथ 'पिछड़ा संगत' था .bashrc

एक पकड़ हालांकि। सभी कार्य पूरी तरह से काम करते हैं, लेकिन मैं यह पता नहीं लगा सकता कि निर्यात प्रणाली कैसे काम करती है।

मेरे पास उन कुछ .bashrcकार्यों का निर्यात किया गया था ताकि मैं उन्हें अन्यत्र उपयोग कर सकूं, जैसे कि स्क्रिप्ट और बाहरी कार्यक्रमों में, के साथ export -f

Zsh में, निर्यात के बारे में बात भी नहीं लगती। क्या यह ऑटोलिंग है? क्या वे दो चीजें समान हैं? मुझे लगता है कि बाहर गंभीरता से एक कठिन समय चल रहा है।


2
यह एक बहुत पुराना सवाल है, लेकिन मैं यह कहना चाहता हूं कि "वर्तमान कामकाजी निर्देशिका और वास्तविक कमांड लाइन अलग-अलग लाइनों पर हैं" का zsh से कोई लेना-देना नहीं है। यह इस बात पर निर्भर करता है कि आपने अपना प्रॉम्प्ट कैसे सेट किया है।
4a1e1

जवाबों:


11

फ़ंक्शंस वाले पर्यावरण चर एक बैश हैक हैं। Zsh में कुछ भी समान नहीं है। आप कोड की कुछ पंक्तियों के साथ भी कुछ ऐसा ही कर सकते हैं। पर्यावरण चर में तार होते हैं; शेलशॉक की खोज से पहले बैश के पुराने संस्करणों को फ़ंक्शन के कोड को एक चर में संग्रहीत किया गया था जिसका नाम फ़ंक्शन का है और जिसका मान () {फ़ंक्शन के कोड के बाद है }। आप इस एन्कोडिंग के साथ चर आयात करने के लिए निम्न कोड का उपयोग कर सकते हैं, और उन्हें बैश जैसी सेटिंग्स के साथ चलाने का प्रयास कर सकते हैं। ध्यान दें कि zsh सभी bash फीचर्स का अनुकरण नहीं कर सकता है, आप जो कुछ भी कर सकते हैं वह थोड़ा करीब हो जाता है (जैसे $fooमान को विभाजित करने और वाइल्डकार्ड का विस्तार करने के लिए, और सरणियों को 0-आधारित बनाना)।

bash_function_preamble='
    emulate -LR ksh
'
for name in ${(k)parameters}; do
  [[ "-$parameters[name]-" = *-export-* ]] || continue
  [[ ${(P)name} = '() {'*'}' ]] || continue
  ((! $+builtins[$name])) || continue
  functions[$name]=$bash_function_preamble${${${(P)name}#"() {"}%"}"}
done

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

अमान्य चर नामों (जैसे BASH_FUNC_myfunc%%) का उपयोग करके वातावरण में बैश के पोस्ट-शेलशॉक संस्करण कार्य करते हैं । यह उन्हें मज़बूती से पार्स करने के लिए कठिन बनाता है क्योंकि zsh पर्यावरण से ऐसे परिवर्तनशील नामों को निकालने के लिए इंटरफ़ेस प्रदान नहीं करता है।

मैं ऐसा करने की सलाह नहीं देता। लिपियों में निर्यात किए गए कार्यों पर भरोसा करना एक बुरा विचार है: यह आपकी स्क्रिप्ट में एक अदृश्य निर्भरता बनाता है। यदि आप कभी भी अपनी स्क्रिप्ट को ऐसे वातावरण में चलाते हैं जिसमें आपका कार्य नहीं है (किसी अन्य मशीन पर, क्रॉन जॉब में, आपकी शेल आरंभीकरण फ़ाइलों को बदलने के बाद ...), तो आपकी स्क्रिप्ट अब काम नहीं करेगी। इसके बजाय, अपने सभी फ़ंक्शंस को एक या अधिक अलग-अलग फ़ाइलों (जैसे कुछ ~/lib/shell/foo.sh) में संग्रहीत करें और उन कार्यों को आयात करके अपनी स्क्रिप्ट शुरू करें जो इसका उपयोग करता है ( . ~/lib/shell/foo.sh)। इस तरह, यदि आप संशोधित करते हैं foo.sh, तो आप आसानी से खोज सकते हैं कि कौन सी स्क्रिप्ट इस पर निर्भर हैं। यदि आप एक स्क्रिप्ट की प्रतिलिपि बनाते हैं, तो आप आसानी से यह पता लगा सकते हैं कि इसे कौन सी सहायक फ़ाइलों की आवश्यकता है।

Zsh (और इससे पहले ksh) स्क्रिप्ट में स्वचालित रूप से कार्यों को लोड करने का एक तरीका प्रदान करके इसे और अधिक सुविधाजनक बनाता है जहां उनका उपयोग किया जाता है। बाधा यह है कि आप प्रति फ़ाइल केवल एक फ़ंक्शन डाल सकते हैं। फ़ंक्शन को ऑटोलॉइड के रूप में घोषित करें, और फ़ंक्शन की परिभाषा को फ़ाइल में डालें जिसका नाम फ़ंक्शन का नाम है। इस फ़ाइल को सूचीबद्ध निर्देशिका में रखें $fpath(जिसे आप FPATHपर्यावरण चर के माध्यम से कॉन्फ़िगर कर सकते हैं )। अपनी स्क्रिप्ट में, के साथ ऑटोलॉइड फ़ंक्शन घोषित करें autoload -U foo

इसके अलावा zsh स्क्रिप्ट को संकलित कर सकता है, ताकि पार्सिंग समय को बचाया जा सके। zcompileकिसी स्क्रिप्ट को संकलित करने के लिए कॉल करें। यह .zwcएक्सटेंशन के साथ एक फ़ाइल बनाता है । यदि यह फ़ाइल मौजूद है, तो autoloadस्रोत कोड के बजाय संकलित फ़ाइल को लोड करेगा। आप एक निर्देशिका में सभी फ़ंक्शन परिभाषाओं को संकलित (पुनः) करने के लिए zrecompileफ़ंक्शन का उपयोग कर सकते हैं ।


1
मजेदार है कि आपके कोड में समान शेलशॉक भेद्यता है bash(यह सत्यापित नहीं करता है कि चर की सामग्री केवल एक फ़ंक्शन परिभाषा है और किसी भी चर नाम को संसाधित करती है जैसे HTTP_HOSTया LC_X)। अच्छा जवाब अन्यथा।
स्टीफन चेज़लस

@ StéphaneChazelas यदि आप पर्यावरण से आयातित कार्यों के साथ कमांड चलाने जा रहे हैं, तो आप बहुत अधिक खो चुके हैं। लेकिन मैंने मनमाने कोड को निष्पादित नहीं करने के लिए आयात कोड अपडेट किया है। हालांकि यह बहुत उपयोगी नहीं है, क्योंकि पोस्ट-शेलशॉक बैश अपने निर्यात किए गए कार्यों को उसी तरह से एनकोड नहीं करता है।
गिल्स एसओ- बुराई को रोकें '

आपने अब CVE-2014-6271 के समतुल्य निर्धारित किया है, लेकिन अभी भी शायद CVE-2014-6277 / 6278 के प्रकार की कई कमजोरियों के संपर्क में हैं ... जैसा कि आप अभी भी किसी भी चर में कोड करने के लिए zsh parser को उजागर कर रहे हैं कुछ है कि कुछ संदर्भों में हमलावरों के नियंत्रण में संभावित हैं (में कोड के रूप में शामिल zsh -c 'functions[f]=$VAR' किया गया है पार्स भले ही fसमारोह कभी नहीं कहा जाता है)। इसका समाधान केवल उन चरों पर विचार करना है जिनके नाम उन जैसे एक आरक्षित टेम्पलेट का पालन करते हैं $BASH_FUNC_x%%, लेकिन जैसा कि आप कहते हैं, zshउन लोगों को सूचीबद्ध या पुनर्प्राप्त करने के लिए कोई एपीआई नहीं है। आपको perlउदाहरण के लिए कॉल करना होगा ।
स्टीफन चेज़लस

7

यदि आप अपने कार्य घोषणा को .zshv में रखते हैं , तो आपका कार्य बिना किसी प्रयास के स्क्रिप्ट से प्रयोग करने योग्य होगा।


आपने मेरे उत्तर को नीचा क्यों दिखाया? कृपया समझाएँ।
रोल्स

अभी भी जवाब की प्रतीक्षा में है और अभी भी काम कर रहा है!
rools

मैंने अभी इस उत्तर की खोज की है और यह एक आदर्श समाधान है।
AFH

मैंने इसे कम नहीं किया। और TBH ओपी .bashrc से सामान निर्यात करने के बारे में पूछ रहा था, जो कि एक बुरा विचार है, इसे स्क्रिप्ट में रखना बेहतर है ताकि आप एक विशाल वातावरण के साथ समाप्त न हों। लेकिन आपका समाधान केवल उसी बुरे विचार का एक प्रकार है, अपनी सभी लिपियों को डालें .zshenvऔर यह बहुत सारे कोड को पार्स करके zsh के हर आह्वान को धीमा कर देता है जो कभी भी उपयोग नहीं किया जाता है। इसके अलावा, यह एक फंक्शन को एक्सपोर्ट करने के समान नहीं है, एक्सपोर्टेड वैरिएबल की तरह, एक एक्सपोर्टेड फंक्शन केवल चाइल्ड प्रोसेस के लिए उपलब्ध है। जबकि आपके द्वारा डाला गया सामान .zshenvहर zsh को उपलब्ध है।
रूपांतरित

अंत में यदि आप अपने द्वारा डाले गए व्यक्तिगत कोड पर भरोसा करते हैं .zshenv, तो आपकी सभी स्क्रिप्ट पूरी तरह से गैर-पोर्टेबल होंगी। आम तौर पर स्क्रिप्ट एक दूसरे पर निर्भर हो सकती है, जो ठीक है, आप उन्हें एक साथ वितरित करते हैं। लेकिन अगर वे विशेष कार्यों में शामिल होते हैं .zshenv, तो कोई भी उनका उपयोग नहीं करना चाहेगा, या उन्हें किसी विशेष के साथ आमंत्रित करना होगा ZDOTDIR, जिससे आपके स्वयं .zshenvको निष्पादित होने से रोका जा सके। यह एक पीड़ा होगी।
रूपांतरित
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.