कैसे bashrc में उपनाम का उपयोग करते समय संभावित संघर्षों के लिए परीक्षण करें?


12

क्या उबा कमांड को शामिल करने वाले bashrc अपडेट के कारण सिस्टम में उत्पन्न सभी कमांड संघर्षों को सूचीबद्ध करने का एक सरल तरीका है?

उदाहरण के लिए, कोई alias ls=/path/to/user-generated/executablebashrc में लिखता है। कैसे पता चलता है कि यह एक वास्तविक कमांड ( ls) है। एक तरह से लगता है कि सभी उपनामों को चलाने से पहले और बाद में बैशाख सोर्सिंग करना और आउटपुट को अलग करना है। क्या कोई बेहतर तरीके हैं?

मैं Ubuntu 12.04 चला रहा हूं।

मार - मार

GNU बैश, संस्करण 4.2.24 (1) -release (i686-pc-linux-gnu)


एक साइड नोट के रूप में, यह आमतौर पर जवाब देने वाले लोगों के लिए अधिक उपयोगी होता है यदि आप बैश के लिए विशिष्ट प्रश्न पूछते समय ओएस संस्करण के बजाय बैश का अपना संस्करण प्रदान करते हैं।
जोर्डनम

@ जोर्डनम अपडेट किया गया।
user13107

जवाबों:


8

यह जानने के लिए कि एलियास द्वारा क्या आज्ञा दी गई है, कुछ इस तरह से करें:

alias | sed 's/^[^ ]* *\|=.*$//g' | while read a; do
  printf "%20.20s : %s\n" $a "$(type -ta $a | tr '\n' ' ')"
done | awk -F: '$2 ~ /file/'

व्याख्या

aliasअकेले सूचीबद्ध उपनामों को सूचीबद्ध करता है और sedउनका नाम निकालता है। जबकि लूप type -taउनमें से प्रत्येक पर चलता है और उन awkपंक्तियों को प्रिंट करता है जिसमें दोनों उपनाम और फ़ाइल होते हैं।


15

आप यह typeपता लगाने के लिए उपयोग कर सकते हैं कि बैश द्वारा एक कमांड की व्याख्या कैसे की जाएगी।


उदाहरण के लिए, यहाँ type lsप्रिंट ls is aliased to `ls --color=auto'
l0b0

उसी के साथ काम करता है which, लेकिन मैं अब नहीं है अगर दोनों (प्रकार, जो) शेल बिल्डरों समान हैं।
गणित

@ मथ: type whichआपको बताता है which is /usr/bin/which, इसलिए यह बिल्टिन नहीं है। इसलिए, यह आपको यह नहीं बता सकता है कि कुछ एक बिलिन है या नहीं (उदाहरण के लिए which echoबनाम type echo)।
कोरोबा

मुझे लगता है कि यह आपके द्वारा उपयोग किए जाने वाले शेल पर निर्भर करता है: type which which is a shell builtinमैं zsh का उपयोग कर रहा हूं।
गणित

@ मथ: मूल प्रश्न टैग / बैश है।
कोरोबा

7

आपके पहले प्रश्न के रूप में, संघर्षों को सूचीबद्ध करने का कोई तरीका नहीं है, क्योंकि bash आंतरिक रूप से हैश तालिका का उपयोग करता है, यह केवल अंतिम ओवरराइड को रिकॉर्ड करता है।

यह पता लगाने के लिए कि क्या कोई कमांड उपनाम है, alias lsअपने मामले में उपयोग करें, यदि यह आपको "नहीं मिला" जैसा कुछ बताता है तो यह एक उपनाम नहीं है, अन्यथा यह है।

मूल फ़ंक्शन को लॉन्च करने के लिए उपनाम की अवहेलना करें, एक स्लैश को उपसर्ग करें, उदाहरण के \lsलिए असली हैशेड ls लॉन्च करेगा, उपनाम को अनदेखा करें।

संपादित करें

यदि आप जल्दी से जानना चाहते हैं कि क्या कमांड एक उपनाम है, तो आप डिबगिंग मोड को सक्षम कर सकते set -xहैं, अब यदि आप निष्पादित करते हैं ls:

यहाँ छवि विवरण दर्ज करें

आपको वास्तविक कमांड का डिबग आउटपुट दिखाई देगा

डिबग मोड को अनसेट करने के लिए, उपयोग करें set -


धन्यवाद। लेकिन aliasहिस्सा नहीं मिला । क्या होगा यदि कोई उपयोगकर्ता नहीं जानता है कि एक कमांड मौजूद है (जैसे ls)? केवल एक चीज जिसे वह चलाने के बाद पता लगता है कि वह alias lsक्या है जिसे मूल रूप से मैप किया गया है और क्या नहीं। मुझे लगता है कि किसी को संघर्ष खोजने के लिए और बिना सभी आदेशों को चलाना होगा।
user13107

@ user13107 ने उत्तर अपडेट किया
daisy

धन्यवाद। मैं ट्रेसिंग कैसे शुरू करूं?
user13107

@ user13107 ने फिर अपडेट किया; -पी
डेज़ी

1
"संघर्षों को सूचीबद्ध करने का कोई तरीका नहीं है" - आप केवल कल्पनाशील नहीं हैं।
Camh

6

आप compgenसभी कमांड और सभी उपनामों की सूची प्राप्त करने के लिए बैश बिलिन का उपयोग कर सकते हैं compgen -ac। इस सूची में कोई भी आदेश जो भी अन्य नाम है, को डुप्लिकेट किया जाएगा, इसलिए सरल भोले समाधान के आउटपुट में डुप्लिकेट की तलाश करना है compgen -ac

हालाँकि, डुप्लिकेट भी दिखाई दे सकता है यदि एक कमांड दो बार रास्ते पर है। उदाहरण के लिए, मेरे पास है /bin/whichऔर /usr/bin/whichइसलिए compgen -acसूची जाएगा whichदो बार भले ही यह एक उपनाम नहीं है।

तो क्या जरूरत है कि सभी डुप्लिकेट को प्राप्त compgen -acकरें और तुलना करें कि उपनाम की सूची में। केवल डुप्लिकेट जो उपनाम भी हैं वे उपनाम हैं जो कमांड छिपाते हैं। हम इसे comm(1)कमांड के साथ और बैश प्रक्रिया प्रतिस्थापन के साथ कर सकते हैं ।

comm -12 <(compgen -a | sort) <(compgen -ac | sort | uniq -d) 

compgen -a | sortसभी उपनामों (के लिए क्रमबद्ध comm) की सूची है। compgen -ac | sort | uniq -dआदेश और उपनाम की सूची से सभी डुप्लिकेट की सूची है। comm -12केवल उन पंक्तियों को आउटपुट करता है जो दोनों के लिए सामान्य हैं।


5

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

bash -x -l -i -c 'exit' 2>&1 | grep ' alias '
  • -x -> डिबगिंग सक्षम करें
  • -l -> लॉगिन शेल
  • -i -> इंटरैक्टिव खोल
  • -c -> आज्ञा

कमांड एग्जिट को चलाना आवश्यक है ताकि शेल वापस आए। -iइस मामले में आवश्यक है क्योंकि पार्टी के लिए एक कमांड अन्यथा चलाने के लिए एक इंटरैक्टिव वातावरण की स्थापना नहीं होता।

यहाँ मेरे सिस्टम से एक उदाहरण है:

$ bash -x -l -i -c 'exit' 2>&1 | grep ' alias '
++ alias 'ls=ls --color=auto'
$ alias -p
alias ls='ls --color=auto'

यह देखने के लिए कि उर्फ ​​फ़ाइल को यह निर्धारित करने के लिए किस फ़ाइल को अंतिम रूप दिया गया था, यह हुआ कि आप grep को बढ़ा सकते हैं:

bash -x -l -i -c 'exit' 2>&1 | grep -E ' (alias|[.]|source) '

यह गलत सकारात्मक लौट सकता है, लेकिन यदि आप मैन्युअल रूप से दिए गए डेटा का निरीक्षण कर रहे हैं तो ठीक होना चाहिए। निष्पादित कमांड के सामने '+' प्रतीकों की संख्या गहराई को दर्शाती है।

+ . /home/jordan/.bashrc
++ alias 'ls=ls --color=auto'
++ . /home/jordan/.foo
+++ alias t=test
++ alias t=test2

इस नमूना आउटपुट में, यह दिखाता है कि .bashrc ls.foo उपनाम के लिए एक उपनाम सेट करता है t, और फिर .bashrc पिछले उपनाम को ओवरराइड करता है t


धन्यवाद। यह निश्चित रूप से उपयोगी है, लेकिन यह देखने में सक्षम नहीं है कि यह संघर्ष बनाने वाले उपनाम कैसे पाता है।
user13107

@ user13107 मैंने कुछ और विवरण जोड़े जो सहायक होने चाहिए। एक नए मूल्य के लिए एक उपनाम सेट करना एक "परस्पर विरोधी" उपनाम नहीं है। यह सामान्य प्रलेखित व्यवहार है, जिसके कारण गोल-गोल तरीके की आवश्यकता होती है।
जोर्डनम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.