सभी उपनामों को एक zsh कमांड लाइन में हल करें


12

मेरे पास उपनाम हैं और मैं कमांड निष्पादित करने से पहले उन सभी को हल करना चाहता हूं। मैं उसको कैसे करू?

यदि कोई ऐसा कार्य है जो किसी भी कुंजी के लिए बाध्य नहीं है तो M-x foobarमेरे लिए भी ठीक है। मैं भी बाहरी कमांड इस्तेमाल कर सकते हैं ( type, command, which, जो कुछ भी)। मैंने थ्रेड से सब कुछ आज़माया "क्यों नहीं" का उपयोग करें? तब क्या उपयोग करें? लेकिन कुछ भी नहीं काम करता है।


3
C-x aकर्सर के तहत उपनाम का विस्तार करता है (यह मानते हुए कि आप पूर्ण प्रणाली का उपयोग कर रहे हैं)।
स्टीफन चेज़लस

ठीक है, _expand_alias (^Xa): expands the word the cursor is on if it is an alias। यह मददगार है, हालांकि अभी भी इसका अफ़सोस है कि bash में पूरी लाइन का विस्तार किया जा सकता है लेकिन zsh में नहीं।
WeISERASoulInSearchOfAnswers

मुझे लगता है कि यह एक बाइंडेबल कमांड लिखना संभव है जो _expand_aliasतब तक आक्रमण करता है जब तक कि एडिट बफ़र नहीं बदलता।
vinc17

जवाबों:


10

ध्यान दें कि Ctrl-Alt-E bashकेवल उपनाम का विस्तार नहीं करता है। यह चर, कमांड प्रतिस्थापन (!), प्रक्रिया प्रतिस्थापन (!), अंकगणित का विस्तार करता है और उद्धरणों को निकालता है (यह फ़ाइल नाम पीढ़ी (ग्लोबिंग) या टिल्ड विस्तार नहीं करता है)।

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

उदाहरण के लिए:

$ a=';w' b=1
$ alias foo=bar
$ b=2; echo $b $a; cd /tmp/dir && for i do foo $(pwd) <(ls); done

अगर मैं M-C-Eयहाँ दबाता हूँ , तो यह मुझे देता है:

$ b=2; echo 1 ;w; cd /tmp/dir && for i do foo / /dev/fd/63; done

जो मुझे पूरी तरह से एक अलग कमांड लाइन देता है (और कल्पना करें कि ऊपर के rm -rf *बजाय अगर मेरे पास होता तो क्या होता pwd) और इसका विस्तार नहीं करताfoo उपनाम का ।

साथ zsh, कार्यों के अंदर का विस्तार उपनाम पर गाइल्स 'नोट पर निर्माण करने के लिए, आप कर सकता है:

expand-aliases() {
  unset 'functions[_expand-aliases]'
  functions[_expand-aliases]=$BUFFER
  (($+functions[_expand-aliases])) &&
    BUFFER=${functions[_expand-aliases]#$'\t'} &&
    CURSOR=$#BUFFER
}

zle -N expand-aliases
bindkey '\e^E' expand-aliases

यह उपनाम तब ही विस्तारित होगा जब वर्तमान कमांड लाइन वाक्यविन्यास रूप से मान्य हो (इसलिए यह सिंटैक्स चेकर के रूप में दोगुना हो जाता है)।

bashMCE के विपरीत , यह भी पूरी तरह से उपनाम हल करता है। उदाहरण के लिए यदि आपके पास:

$ alias ll='ls -l'; alias ls='ls --color'
$ ll

इसका विस्तार किया जाएगा:

$ ls --color -l

ध्यान दें कि यह वाक्यविन्यास को भी विहित करता है, जैसे:

$ for i (*) cmd $i; foo

इसे बदल दिया जाएगा:

$ for i in *
        do
                cmd $i
        done
        foo

यह छोटी गाड़ी है। यदि मेरे पास है alias ls='ls --color'और टाइप C-x aकरता है ls, तो मुझे मिलता है: \ls --color(ताकि नए lsको एक उपनाम के रूप में गलत नहीं समझा जाए)। लेकिन आपके साथ expand-aliases, मुझे यह मिलता है: ls --colorपरिणाम को अस्पष्ट बनाकर।
vinc17

@ vinc17, यह अस्पष्ट नहीं है कि यह पूरी तरह से उर्फ ​​को हल करता है (उस संबंध में, यह bashसमकक्ष से कम छोटी गाड़ी है )। लेकिन यह सच है कि यदि आप उसके बाद कमांड चलाते हैं, तो आपको अन्य प्रकार का उपनाम विस्तार (जैसे bash) मिलेगा , इसलिए आदर्श रूप से आप अन्य रूप से उपनाम एक्सटेंशन को अक्षम करना चाहते हैं, इसलिए उदाहरण के लिए इसे एक में लपेटें (){ setopt localoptions noexpandalias; ...; }। ध्यान दें कि आप कह सकते हैं कि _expand_aliasछोटी गाड़ी है और साथ ही यह उर्फ ​​का विस्तार करता है जब इसे चलाया जाता है \ls
स्टीफन चेजलस

@ vinc17, द्वारा किया गया बैकस्लैश _expand_aliasभी आसानी से की तरह मूर्ख बना दिया गया है alias 'foo=repeat 3 foo'या alias ls='ls --color'; alias '\ls=echo fooled'। यहां कोई सही समाधान नहीं है।
स्टीफन चेज़लस

के बारे _expand_aliasमें alias 'foo=repeat 3 foo', मैं एक बग के रूप में लापता बैकस्लैश का संबंध होगा। और alias '\ls=echo fooled'अनुमति नहीं दी जानी चाहिए; यहाँ मैं bash पसंद करते हैं, जो कहते हैं: bash: alias: '\ls': invalid alias name
vinc17

@ vinc17, मैं नहीं देख सकता कि कैसे कुछ और के रूप में देखा जा सकता है लेकिन इसमें एक सीमा है bash। यदि आप बैकलेस के साथ उपनाम पसंद नहीं करते हैं, तो उनका उपयोग न करें, लेकिन आप शेल को अस्वीकार क्यों करना चाहेंगे? जबकि उपनाम एक गरीब आदमी के कार्य हैं, जो बॉश-जैसे गोले में, csh (जहां से आते हैं) में बदल जाते हैं, वे ऐसे कार्य करने के लिए हैक्स होते हैं जो फ़ंक्शंस के साथ नहीं किए जा सकते हैं, मैक्रो विस्तार के कुछ रूप जो शेल पार्सर में जल्दी हुक करते हैं , मैं इसे क्या कर सकते हैं को सीमित करने में बात नहीं दिखती।
स्टीफन चेज़लस

6

यदि आप एक कमांड लाइन को फंक्शन डेफिनिशन में स्टफ करते हैं और फिर फंक्शन को प्रिंट करते हैं, तो एलियास का विस्तार होगा। आपको सामान्यीकृत व्हाट्सएप भी मिलेगा।

% alias foo='bar -1'
% alias bar='qux -2'
% f () foo -3
% which f
f () {
        qux -2 -1 -3
}

यह सब एक इंटरैक्टिव कमांड में डालने के लिए, आप एक zle विजेट बना सकते हैं। आप functionsसरणी में एक प्रविष्टि में इसके कोड को भरकर सीधे एक फ़ंक्शन को परिभाषित कर सकते हैं ; जब आप वापस पढ़ेंगे तो आपको सामान्यीकरण प्रभाव मिलेगा।

normalize-command-line () {
  functions[__normalize_command_line_tmp]=$BUFFER
  BUFFER=${${functions[__normalize_command_line_tmp]#$'\t'}//$'\n\t'/$'\n'}
  ((CURSOR == 0 || CURSOR = #BUFFER)
  unset 'functions[__normalize_command_line_tmp]'
}
zle -N normalize-command-line
bindkey  normalize-command-line

आपको preexecहुक में समान सामान्यीकरण प्रभाव मिलता है । उपनाम का विस्तार उस समय किया जाता है जब कोई फ़ंक्शन ऑटोलोडेड होता है ( autoload -Uजिसका उपयोग आमतौर पर उर्फ ​​विस्तार से बचने के लिए किया जाता है)।

_expand_aliasअगर यह एक उपनाम है पूरा होने के समारोह कर्सर के तहत शब्द फैलता है। यह aliasesसरणी का उपयोग करता है । यह पुनरावर्ती नहीं है। आप का उपयोग करके एक अधिक सामान्य उर्फ ​​विस्तारक को लागू कर सकते हैं aliases, लेकिन यह कुछ मुश्किल है, क्योंकि उन स्थानों का पता लगाना जहां उपनामों का विस्तार किया गया है, वे शेल सिंटैक्स के साथ आंतरिक रूप से जुड़े हुए हैं।


2
मैंने हमेशा autoload -Uकेवल इसलिए इस्तेमाल किया क्योंकि zsh डॉक्यूमेंटेशन इसकी सिफारिश करता है, लेकिन मैंने कभी नहीं समझा कि -Uवास्तव में मैंने क्या किया है जब तक मैं इसे पढ़ता हूं :)। इसके अलावा के लिए किसी को भी रुचि, एक आह्वान कर सकते हैं _expand_alias , कमांड लाइन में अपना उपनाम टाइपिंग मारकर सीधे ढंग से काम <Esc>, x, minibuffer शुरू करने के लिए है, तो टाइप_expand_alias<Enter>
the_velour_fog

2

यदि आपके पास कई नेस्टेड फैंसी उपनाम हैं और आपको यकीन नहीं है कि वास्तव में उनके साथ कौन सा zsh कर रहा है और किस क्रम में कमांड का विकल्प दिया जाता है तो आप हमेशा zsh से शुरुआत कर सकते हैं -x विकल्प के । यह कमांड और आर्ग्युमेंट्स को प्रिंट करेगा क्योंकि वे निष्पादित होते हैं।

हालाँकि इस बात का ध्यान रखें कि यह विकल्प डिबगिंग उद्देश्य के लिए है, इसलिए यह बहुत ही बेकार सामान को सिर्फ zsh -xमंगलाचरण के बाद प्रिंट करता है (मूल रूप से प्रत्येक और प्रत्येक फ़ंक्शन / विजेट / प्लगइन आपके .zshrc का), और कमांड निष्पादन के दौरान यह विशेष रूप से क्रिया भी हो सकता है। अगर आपने परिभाषित किया है preexecऔरprecmd हुक किया है।

मुझे यह भी उल्लेख करना चाहिए, कि यह केवल उन कमांडों को प्रिंट करता है जिन्हें अंततः निष्पादित किया जाता है, और अलग-अलग कमांड को अलग-अलग मुद्रित किया जाता है

alias a='echo a'
alias b='echo b'
alias c='echo c'
alias d='echo d'
a && b || c; d

तुम देखोगे

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