"कमांड नहीं मिला" जब sudo'ing फ़ंक्शन ~ / .zshrc से आता है


10

मैं अपने में एक समारोह है ~/.zshrc:

findPort() {
    lsof -t -i :$1
}

सामान्य आह्वान है findPort 3306

मैं इसे उन्नत विशेषाधिकार के साथ चलाना चाहता हूं। लेकिन मुझे "कमांड नहीं मिला"।

  git 🍔 sudo findPort 3306
sudo: findPort: command not found

मुझे लगता है कि इसका कारण यह है कि रूट उपयोगकर्ता या तो एक गैर-संवादात्मक शेल के रूप में चलता है (इस प्रकार एक .zshrc का संदर्भ नहीं देता है), या एक अलग को संदर्भित करता है .zshrc

मैंने इसी तरह के सवालों को देखा है alias, लेकिन उपयोगकर्ता द्वारा परिभाषित कार्यों के बारे में कोई सवाल नहीं है। इस समस्या के बारे aliasमें जवाब में एक उपनाम शामिल करना शामिल है ~/.zshrc:

alias sudo='nocorrect sudo '

या शायद:

alias sudo='sudo '

मैंने इन दोनों समाधानों की कोशिश की है, और समस्या अभी भी मौजूद है (हाँ, मैंने शेल को फिर से शुरू किया है)।

मैंने यह sudo chshसुनिश्चित करने के लिए दौड़ने की भी कोशिश की है कि मेरा रूट शेल अंडर रन करता है zsh। इनमें से कोई भी समाधान "कमांड नहीं मिला" समस्या को दूर करता है।

क्या सूडो के तहत मेरे उपयोगकर्ता-परिभाषित कार्यों को चलाने का एक तरीका है?


इसे भी देखें: unix.stackexchange.com/questions/181414/… ( झंडोत्तोलन नहीं किया क्योंकि zsh की अपनी चाल है)
muru

जवाबों:


13

sudoएक खोल के माध्यम से नहीं सीधे आदेशों चलाता है, और यहां तक कि अगर यह है कि आदेश को चलाने के लिए एक खोल भाग गया, यह एक नया खोल मंगलाचरण होगा, और नहीं एक है कि आपके पढ़ता है ~/.zshrc(भले ही वह एक इंटरैक्टिव खोल शुरू कर दिया, यह शायद पढ़ें rootकी ~/.zshrc, जब तक आप चर को sudoरीसेट नहीं करने के लिए कॉन्फ़िगर नहीं किए जाते हैं तब तक आपका नहीं $HOME)।

यहां, आपको sudoएक नया zshशेल शुरू करने के लिए बताना होगा , और उस फ़ंक्शन को चलाने से पहले zshअपने पढ़ने के लिए बताना होगा ~/.zshrc:

sudo zsh -c '. $0; "$@"' ~/.zshrc findPort 3306

या:

sudo zsh -c '. $0; findPort 3306' ~/.zshrc

या नए zshद्वारा आमंत्रित के साथ अपने वर्तमान zsh कार्यों को साझा करने के लिए sudo:

sudo zsh -c "$(functions); findPort 3306"

हालाँकि, यदि आपके पास बहुत सारे फ़ंक्शन परिभाषित हैं (जैसे कि पूर्ण सिस्टम का उपयोग करते समय) तो आपको एक arg सूची बहुत लंबी त्रुटि प्राप्त हो सकती है । इसलिए आप इसे findPortफ़ंक्शन तक सीमित कर सकते हैं (और यदि यह किसी अन्य फ़ंक्शन पर निर्भर करता है तो कोई भी):

sudo zsh -c "$(functions findPort); findPort 3306"

आप भी कर सकते हैं:

sudo zsh -c "(){$functions[findPort]} 3306"

findPortकिसी अनाम फ़ंक्शन में फ़ंक्शन के कोड को एम्बेड करने के लिए जिसे आप 3306 तर्क पास करते हैं। या और भी:

sudo zsh -c "$functions[findPort]" findPort 3306

(इनलाइन स्क्रिप्ट के लिए पारित किया -c है समारोह के शरीर)।

आप एक सहायक समारोह का उपयोग कर सकते हैं जैसे:

zsudo() sudo zsh -c "$functions[$1]" "$@"

प्रयोग नहीं करें:

sdo () {sudo zsh -c ”() {$ कार्यों [$ 1]} $ {@: 2}”}

जैसा कि sdoशेल पार्सिंग के एक और स्तर से गुजरना होगा। की तुलना करें:

$ e() echo "$@"
$ sdo e 'tname;uname'
tname
Linux
$ zsudo e 'tname;uname'
tname;uname

मुझे ऐसा समाधान चाहिए जो टाइपिंग जितना छोटा हो sudo। मैं बस करने के लिए आपके अनाम फ़ंक्शन समाधान को अनुकूलित करने में सक्षम था । मैंने निम्नलिखित फ़ंक्शन को अपने साथ जोड़ा है ~/.zshrc, जो कि उन्नत विशेषाधिकारों के साथ अन्य कार्यों को चलाने के लिए एक फ़ंक्शन है :sdo() { sudo zsh -c "(){$functions[$1]} ${@:2}" }
बिर्चलैब्स

1
@ बिर्चलैब्स, संपादित करें
स्टीफन चेज़लस

धन्यवाद; मैंने आपके द्वारा प्रस्तावित नए शॉर्टकट का उपयोग करने के लिए अपना उत्तर अपडेट कर दिया है।
बिर्चलैब्स

सुडो के माध्यम से निष्पादित स्क्रिप्ट में फ़ंक्शन परिभाषा जोड़ना स्मार्ट है। लेकिन इतना स्मार्ट नहीं कि अगर वह फंक्शन किसी दूसरे फंक्शन (ऑटोलेडेड या नहीं) का इस्तेमाल करे।
डेमियन फ्लैम

3

मेरे लिए एक बहुत ही सरल उपाय एक इंटरैक्टिव शेल का उपयोग करना था sudo -s, जो कि zsh (5.2) के मेरे macOS बंडल संस्करण पर काम करता है। यह मुझे मेरे कार्यों से प्रदान करता है ~/.zshrc

Sudo manpage से, जो वास्तव में इस व्यवहार को इंगित नहीं करता है:

-s, --shell
शेल शेल के वैरिएबल द्वारा निर्दिष्ट शेल को चलाएं यदि यह सेट किया गया है या शेल उपयोगकर्ता के पासवर्ड डेटाबेस प्रविष्टि द्वारा निर्दिष्ट है। यदि कोई कमांड निर्दिष्ट है, तो इसे शेल के -c विकल्प के माध्यम से निष्पादन के लिए शेल में पास किया जाता है। यदि कोई कमांड निर्दिष्ट नहीं है, तो एक इंटरैक्टिव शेल निष्पादित किया जाता है।

मुझे यकीन नहीं है कि आपका उपयोग मामला क्या है, लेकिन मुझे संदेह है कि आप एक इंटरैक्टिव समाधान की तलाश कर रहे हैं।


यह वास्तव में काम करता है। हालांकि यह काफी वर्कफ़्लो नहीं है जो मेरे मन में था। मेरी इच्छा अपने सामान्य उपयोगकर्ता के रूप में एक प्रॉम्प्ट में बने रहने की है, और केवल अपने उपयोगकर्ता-परिभाषित फ़ंक्शन myFuncको टाइप करके sudo myFuncबढ़ाता हूं - उसी तरह मैं किसी भी प्रक्रिया को बढ़ाऊंगा (जैसे sudo rm -rf .)। यह समाधान मेरे पूरे प्रॉम्प्ट और भविष्य के सभी कार्यों को बढ़ाता है, साथ ही साथ भविष्य के सभी कार्यों के लिए मेरे उपयोगकर्ता को बदल देता है - जो कि थोड़ा ओवरकिल है।
बिर्चलैब्स

sudo -sआदेश सुपर उपयोगकर्ता के रूप में अपने खोल का एक और उदाहरण का शुभारंभ करेंगे। यदि आप उस कमांड को अंतःक्रियात्मक रूप से निष्पादित करते हैं, तो आपका नया शेल इंटरैक्टिव होगा। लेकिन कमांड आपके शेल में sudo -s findPort 3306कमांड findPort 3306को सुपरयुसर के रूप में चलाएगा और फिर उस कमांड के स्टेटस कोड के साथ बाहर निकल जाएगा।
डेमियन फ्लैम

2

मैं स्टीफन चेज़लस के उत्तर में वर्णित समाधानों में से एक के लिए पुन: प्रयोज्य शॉर्टहैंड का उत्पादन करने में सक्षम था । [संपादित करें: स्टीफन ने मेरे द्वारा प्रस्तावित मूल शॉर्टकट पर पुनरावृत्ति की है; यहाँ वर्णित कोड उनके बनाने का एक नया संस्करण है]

इसे अपने में रखें ~/.zshrc:

sdo() sudo zsh -c "$functions[$1]" "$@"

अब आप sdo" sudoकेवल उपयोगकर्ता-परिभाषित कार्यों के लिए " के रूप में उपयोग कर सकते हैं ।

उस sdoकाम की पुष्टि करने के लिए : आप इसे उपयोगकर्ता-निर्धारित फ़ंक्शन पर आज़मा सकते हैं जो आपके उपयोगकर्ता नाम को प्रिंट करता है।

 birch@server ~/ 🍔 test() whoami

 birch@server ~/ 🍔 test
birch

 birch@server ~/ 🍔 sdo test
root

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.