क्या आप मेरे लिए इस बैश कोड में इन तीन चीजों की व्याख्या कर सकते हैं?


10

functionमेरी .bashrcफाइल में ए है । मुझे पता है कि यह क्या करता है, यह एक्स कई निर्देशिकाओं के साथ कदम बढ़ाता हैcd

यह रहा:

up()
{
    local d=""
    limit=$1
    for ((i=1 ; i <= limit ; i++))
      do
        d=$d/..
      done
    d=$(echo $d | sed 's/^\///')
    if [ -z "$d" ]; then
      d=..
    fi
    cd $d
}

लेकिन क्या आप मेरे लिए इसमें से ये तीन बातें समझा सकते हैं?

  1. d=$d/..
  2. sed 's/^\///'
  3. d=..

ऐसा क्यों नहीं करते:

up()
{
    limit=$1

    for ((i=1 ; i <= limit ; i++))
    do
        cd ..
    done
}

उपयोग:

<<<>>>~$ up 3
<<<>>>/$

जवाबों:


24
  1. d=$d/..चर /..की वर्तमान सामग्री में जोड़ता है ddखाली शुरू होता है, फिर पहला पुनरावृत्ति इसे बनाता है /.., दूसरा /../..आदि।

  2. sed 's/^\///'पहला गिरता है /, इसलिए /../..बन जाता है  ../..(यह एक पैरामीटर विस्तार का उपयोग करके किया जा सकता है d=${d#/})।

  3. d=.. केवल इसकी स्थिति के संदर्भ में समझ में आता है:

    if [ -z "$d" ]; then
      d=..
    fi

    यह सुनिश्चित करता है कि, यदि dइस बिंदु पर खाली है, तो आप मूल निर्देशिका में जाते हैं। ( upकोई तर्क नहीं के बराबर है cd ..।)

यह दृष्टिकोण पुनरावृत्ति से बेहतर है cd ..क्योंकि यह संरक्षित करता है cd -- एक चरण में पिछली निर्देशिका (उपयोगकर्ता के दृष्टिकोण से) पर लौटने की क्षमता।

समारोह को सरल बनाया जा सकता है:

up() {
  local d=..
  for ((i = 1; i < ${1:-1}; i++)); do d=$d/..; done
  cd $d
}

यह मानता है कि हम कम से कम एक स्तर को ऊपर ले जाना चाहते हैं, और n - 1 स्तर जोड़ता है, इसलिए हमें /खाली के लिए अग्रणी या जांच को हटाने की आवश्यकता नहीं है $d

एथेना का उपयोग करना jot( athena-jotडेबियन में पैकेज):

up() { cd $(jot -b .. -s / "${1:-1}"); }

( ग्लेन जैकमैन द्वारा सुझाए गए एक संस्करण पर आधारित )।


हाँ, $OLDPWDमन में आघात हो रहा है। और zsh पर dirstack cdका उपयोग करने के लिए सेट के साथ , वह भी।
मूरू

क्या केवल लूप में उपयोग $1करने के limitबजाय असाइन करने का कोई कारण है $1?
निक

1
@kundor यह सुनिश्चित करता है कि डिफ़ॉल्ट 0 है ( शेल अंकगणित देखें )। हम ${1:-1}इसके बजाय, ग्लेन के रूप में उपयोग कर सकते हैं ।
स्टीफन किट

@ कुंडोर भी मानव पठनीयता। एक अच्छी तरह से नामित चर बताता है कि इरादा अर्थ या उद्देश्य पहला तर्क की है जब आप शुरू यह निकालना कोड को समझने के पहले पता समारोह क्या करता है या समाप्त करने के लिए बिना समारोह पढ़ना,।
mtraceur

2

लेकिन क्या आप मेरे लिए इसमें से ये तीन बातें समझा सकते हैं?

  1. d = $ d / ..

    यह var की वर्तमान सामग्रियों को संगृहीत dकरता है /..और इसे वापस असाइन करता है d
    अंतिम परिणाम की dतरह बार-बार स्ट्रिंग करना है /../../../..

  2. sed 's / ^ ///'

    आपके द्वारा पोस्ट किए गए कोड में /आपूर्ति की गई स्ट्रिंग, d($ $ d) से अग्रणी निकालें ।
    संभवतः sed 's|^/||'बैकस्लैश से बचने के लिए बेहतर लिखा गया है।

    एक वैकल्पिक (तेज और सरल) लिखना है d=${d#/}

  3. d = ..

    स्ट्रिंग ..को var में असाइन करें d
    यह केवल यह सुनिश्चित करने के तरीके के रूप में समझ में आता है कि परीक्षण के संकेतों के dकम से कम एक .. होने if [ -z "$d" ]; thenकी संभावना dहै कि var खाली है। और यह केवल इसलिए हो सकता है क्योंकि सेड कमांड एक पात्र को हटा रहा है d
    यदि वर्ण को d से निकालने की कोई आवश्यकता नहीं है, तो sedया की कोई आवश्यकता नहीं है if


आपके प्रश्न में कोड हमेशा कम से कम एक डीआईआर को ऊपर ले जाएगा।

बेहतर

  • local dयह सुनिश्चित करने के लिए पर्याप्त है कि चर खाली है, और कुछ नहीं चाहिए।
    हालाँकि, स्थानीय केवल कुछ गोले जैसे बैश या डैश में काम करता है। विशिष्ट में, ksh(as yash) के पास localकमांड नहीं है । एक अधिक पोर्टेबल समाधान है:

    [ "$KSH_VERSION$YASH_VERSION" ] && typeset c='' d='' i='' || local c='' d='' i=''
  • for((वाक्य रचना पोर्टेबल नहीं है। बेहतर कुछ का उपयोग करें:

    while [ "$((i+=1))" -lt "$limit" ]; do
  • मजबूत।
    यदि फ़ंक्शन को दिए गए मान पहले तर्क नकारात्मक या पाठ हो सकते हैं, तो फ़ंक्शन उन मानों को संसाधित करने के लिए मजबूत होना चाहिए।
    सबसे पहले, की सुविधा देता है केवल संख्या (मैं इस्तेमाल करेंगे करने के लिए मूल्यों की सीमा cके लिए count):

    c=${1%%[!0-9]*}

    और फिर गणना मान को केवल सकारात्मक मानों तक सीमित करें:

    let "c = (c>0)?c:0"

यह फ़ंक्शन जल्दबाजी में 0 या किसी भी पाठ (त्रुटियों के बिना) को स्वीकार करेगा:

up()
{
    [ "$KSH_VERSION$YASH_VERSION" ] && typeset c='' d='' i='' || local c='' d='' i=''
    c=${1%%[!0-9]*}
    c=$(((c>0)?c:0))
    while [ "$((i+=1))" -le "$c" ]; do d="$d../"; done
    echo \
        cd "${d%/}"         # Removing the trailing / is not really needed for cd
                            # but it is nice to know it could be done cleanly.
}

up 2
up 0
up asdf

echo \जब आप फ़ंक्शन का परीक्षण कर चुके हों, तो निकालें ।

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