ऑब्जेक्ट-उन्मुख शेल * निक्स के लिए


38

प्रस्तावना: मुझे बैश पसंद है और किसी भी तरह के तर्क या पवित्र-युद्ध को शुरू करने का कोई इरादा नहीं है, और उम्मीद है कि यह एक अत्यंत भोला सवाल नहीं है।

यह सवाल कुछ हद तक सुपरयुजर के इस पोस्ट से संबंधित है , लेकिन मुझे नहीं लगता कि ओपी वास्तव में जानता था कि वह क्या मांग रहा था। मैं विंडोज पर FreeBSD, linux, OS X, और cygwin पर बैश का उपयोग करता हूं। मुझे हाल ही में विंडोज पर पॉवरशेल के साथ व्यापक अनुभव मिला है।

क्या पहले से उपलब्ध या कार्यों में * निक्स के लिए एक शेल है, जो बैश के साथ संगत है, लेकिन मिश्रण में ऑब्जेक्ट-ओरिएंटेड स्क्रिप्टिंग की एक परत जोड़ता है? केवल एक चीज जो मुझे पता है कि करीब आती है, अजगर कंसोल है, लेकिन जहां तक ​​मैं बता सकता हूं कि यह मानक शेल वातावरण तक पहुंच प्रदान नहीं करता है। उदाहरण के लिए, मैं सिर्फ cd ~और lsफिर chmod +x fileअजगर कंसोल के अंदर नहीं जा सकता । मुझे मानक यूनिक्स बायनेरिज़ के बजाय उन कार्यों को करने के लिए अजगर का उपयोग करना होगा, या बायोनरीज़ को पायनॉन कोड का उपयोग करके कॉल करना होगा।

क्या ऐसा शेल मौजूद है?


3
नहीं है पाश लेकिन वह भी बहुत कुछ बैश की तरह से Powershell की तरह।
21

1
@ephemient शायद आपको pash के लिए एक उत्तर लिखना चाहिए ... हालाँकि मुझे कुछ भी पता नहीं है 'मुक्केबाज़ी, iirc, powerhell एक OO खोल है।
xenoterracide

4
अरे, आपको ipython को देखना चाहिए । यदि आप एक अभिव्यक्ति दर्ज करते हैं जो अजगर के रूप में समझ में नहीं आता है, तो वह इसे शेल कमांड में मैप करने की कोशिश करेगा। उदाहरण के लिए, सामान जैसे cd ~बाद lsमें बाश में काम करता है। आप जैसे आदेशों के साथ पायथन चर (पंक्तियों की सूची। सॉर्ट) की आउटपुट भी असाइन कर सकते हैं listing = !ls
intuited

@intuited: कमाल है, मैं इसकी जाँच करूँगा
रॉबर्ट एस सियाकियो

1
@intuited: मेरे द्वारा किए गए सामान के लिए iPython बहुत अच्छा रहा है, धन्यवाद!
रॉबर्ट एस सियासीओ

जवाबों:


43

मैं एक शेल में तीन वांछनीय सुविधाओं के बारे में सोच सकता हूं:

  • इंटरएक्टिव प्रयोज्य: सामान्य कमांड टाइप करने के लिए त्वरित होना चाहिए; समापन; ...
  • प्रोग्रामिंग: डेटा संरचनाएं; संगामिति (नौकरी, पाइप, ...); ...
  • सिस्टम एक्सेस: फाइल, प्रोसेस, विंडो, डेटाबेस, सिस्टम कॉन्फ़िगरेशन के साथ काम करना ...

यूनिक्स के गोले इंटरेक्टिव पहलू पर ध्यान केंद्रित करते हैं और अधिकांश सिस्टम एक्सेस और कुछ प्रोग्रामिंग को बाहरी उपकरणों में उप-विभाजित करते हैं, जैसे:

  • साधारण गणित के लिए बी.सी.
  • openssl क्रिप्टोग्राफी के लिए
  • पाठ प्रसंस्करण के लिए sed , awk और अन्य
  • मूल टीसीपी / आईपी नेटवर्किंग के लिए एन.सी.
  • ftp एफ़टीपी के लिए
  • mail, Mail, mailx, आदि बुनियादी ई-मेल के लिए
  • cron निर्धारित कार्यों के लिए
  • बुनियादी एक्स विंडो हेरफेर के लिए wmctrl
  • dcop केडीई ≤3.x पुस्तकालयों के लिए
  • dbus उपकरण ( dbus-*या qdbus ) विभिन्न सिस्टम जानकारी और विन्यास कार्यों के लिए (जैसे केडीई के रूप में आधुनिक डेस्कटॉप वातावरण सहित ≥4)

कई, सही तर्क या पाइप किए गए इनपुट के साथ कमांड को लागू करके कई चीजें की जा सकती हैं। यह एक बहुत शक्तिशाली दृष्टिकोण है - बेहतर कार्य के प्रति एक उपकरण है जो इसे अच्छी तरह से करता है, एक एकल प्रोग्राम की तुलना में जो सब कुछ करता है लेकिन बुरी तरह से - लेकिन इसकी सीमाएं हैं।

यूनिक्स गोले की एक प्रमुख सीमा है, और मुझे संदेह है कि यह आपके "ऑब्जेक्ट-ओरिएंटेड स्क्रिप्टिंग" आवश्यकता के बाद है, यह है कि वे एक कमांड से दूसरे तक जानकारी को बनाए रखने, या कमांडों को कट्टरपंथियों की तुलना में बेहतर तरीके से संयोजित करने के लिए अच्छे नहीं हैं। एक पाइपलाइन। विशेष रूप से, अंतर-कार्यक्रम संचार पाठ-आधारित है, इसलिए अनुप्रयोगों को केवल तभी जोड़ा जा सकता है जब वे अपने डेटा को एक संगत तरीके से क्रमबद्ध करते हैं। यह एक आशीर्वाद और अभिशाप दोनों है: सब कुछ-पाठ-पाठ दृष्टिकोण सरल कार्यों को जल्दी से पूरा करना आसान बनाता है, लेकिन अधिक जटिल कार्यों के लिए बाधा को बढ़ाता है।

इंटरएक्टिव प्रयोज्यता भी कार्यक्रम की स्थिरता के खिलाफ चलती है। इंटरएक्टिव कार्यक्रम छोटा होना चाहिए, थोड़ा उद्धृत करने की आवश्यकता है, आपको चर घोषणाओं या टाइपिंग से परेशान न करें, आदि बनाए रखने योग्य कार्यक्रम पठनीय होना चाहिए (इसलिए कई संक्षिप्त नहीं हैं), पठनीय होना चाहिए (इसलिए आपको आश्चर्य नहीं है कि एक नंगे शब्द है या नहीं एक स्ट्रिंग, एक फंक्शन नेम, एक वैरिएबल नेम, इत्यादि) में स्थिरता की जाँच होनी चाहिए जैसे कि वेरिएबल डिक्लेरेशन और टाइपिंग इत्यादि।

संक्षेप में, एक खोल तक पहुँचने के लिए एक कठिन समझौता है। ठीक है, यह उदाहरण पर, शेख़ी अनुभाग को समाप्त करता है।


  • पर्ल शैल (psh) "पर्ल की शक्ति के साथ एक यूनिक्स शेल के इंटरैक्टिव प्रकृति को जोड़ती है"। शेल सिंटैक्स में सरल कमांड (यहां तक ​​कि पाइपलाइन) दर्ज किए जा सकते हैं; बाकी सब कुछ पर्ल है। परियोजना लंबे समय से विकास में नहीं है। यह प्रयोग करने योग्य है, लेकिन उस बिंदु तक नहीं पहुंचा है जहां मैं इसे शुद्ध पर्ल (स्क्रिप्टिंग के लिए) या शुद्ध शेल (अंतःक्रियात्मक या स्क्रिप्टिंग के लिए) का उपयोग करने पर विचार करूंगा।

  • IPython एक बेहतर इंटरैक्टिव पायथन कंसोल है, जो विशेष रूप से संख्यात्मक और समानांतर कंप्यूटिंग पर लक्षित है। यह अपेक्षाकृत युवा परियोजना है।

  • irb (इंटरेक्टिव रूबी) पाइथन कंसोल के रूबी के बराबर है।

  • scsh एक योजना कार्यान्वयन है (यानी एक सभ्य प्रोग्रामिंग भाषा) जिस तरह की प्रणाली बाइंडिंग है, जो पारंपरिक रूप से यूनिक्स के गोले (स्ट्रिंग्स, प्रोसेस, फाइल्स) में पाई जाती है। हालांकि यह एक इंटरैक्टिव शेल के रूप में उपयोग करने योग्य नहीं है।

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

  • मछली एक यूनिक्स शैली के खोल में एक साफ शुरुआत है। इसमें बेहतर प्रोग्रामिंग या सिस्टम एक्सेस फीचर्स नहीं हैं। क्योंकि यह श के साथ संगतता को तोड़ता है, इसमें बेहतर सुविधाओं को विकसित करने के लिए अधिक जगह है, लेकिन ऐसा नहीं हुआ है।


परिशिष्ट: यूनिक्स टूलबॉक्स का एक और हिस्सा कई चीजों को फाइलों के रूप में मान रहा है:

  • अधिकांश हार्डवेयर डिवाइस फ़ाइलों के रूप में पहुंच योग्य हैं।
  • लिनक्स के तहत, /sysअधिक हार्डवेयर और सिस्टम नियंत्रण प्रदान करता है।
  • कई यूनिक्स वेरिएंट पर, प्रक्रिया नियंत्रण /procफाइलसिस्टम के माध्यम से किया जा सकता है ।
  • FUSE के लिए नई फाइलसिस्टम लिखना आसान है। मक्खी पर फ़ाइल स्वरूपों को परिवर्तित करने, विभिन्न नेटवर्क प्रोटोकॉल पर फ़ाइलों तक पहुँचने, अभिलेखागार के अंदर देखने, आदि के लिए पहले से मौजूद फाइल सिस्टम हैं।

हो सकता है कि यूनिक्स के गोले का भविष्य कमांड के माध्यम से बेहतर सिस्टम एक्सेस (और कमांड को संयोजित करने के लिए बेहतर नियंत्रण संरचनाएं) नहीं है, लेकिन फाइल सिस्टम के माध्यम से बेहतर सिस्टम एक्सेस (जो कुछ अलग तरीके से संयोजित होता है - मुझे नहीं लगता कि हमने महत्वपूर्ण मुहावरों की तरह काम किया है) शेल पाइप) अभी तक) हैं।


1
आप सिर पर कील मारते हैं, जब आप कहते हैं कि "मुझे संदेह है कि यह आपके बाद है"। यह सवाल पूछने का मुख्य कारण यह है कि मुझे यूनिक्स टूल्स की शक्ति पसंद है, लेकिन कार्यक्रमों के बीच पाठ-आधारित बातचीत निश्चित रूप से 'और अधिक जटिल कार्यों के लिए एक बाधा खड़ी करती है'। मैंने अपने प्रोग्रामिंग दिनों को पाठ पार्सर्स लिखने के लिए पर्याप्त खर्च किया है :) मुझे लगता है कि यह एक बहुत अच्छी तरह से सोचा हुआ उत्तर है। यह मुद्दे के दिल और विषय की जटिलता के लिए मिलता है। काश मैं इसे दो बार
उखाड़

1
IPython के लिए +1, हालाँकि मुझे पता नहीं है कि ओपी क्या करना चाहता है।
फालमरी

1
यह एक महान जवाब है: मैं ईमानदारी से सोचता हूं कि एक दिलचस्प पीएचडी थीसिस के बीज यहां हैं।
जिग्गी

1
@RobertSCiaccio यह उत्तर सिर्फ एक हालिया पोस्ट में लिंक किया गया था, और पाठ पार्स के बारे में आपकी टिप्पणी मुझे सोच में पड़ गई ... यदि पाठ पार्सिंग आपके "जटिल कार्यों" को पूरा करने के लिए पर्याप्त है, तो क्या आपके पास एक छोटी स्क्रिप्ट या प्रोग्राम नहीं हो सकता है जो नकल करता है यह और यह आपके bash लिपियों में किसी प्रकार के फ़ंक्शन के रूप में उपयोग करता है? बस एक विचार है, मेरे पास बोलने के लिए मेरे बेल्ट के तहत ज्यादा बैश स्क्रिप्टिंग का अनुभव नहीं है।
18

1
@onlyanegg किस तरह से मछली को "वस्तु-उन्मुख" कहा जा सकता है? मछली मुख्य रूप से सरल होने का लक्ष्य रखती है। क्या कोई ऐसा तरीका है जिसमें यह विकल्पों की तुलना में अधिक शक्तिशाली है?
गिल्स एसओ- बुराई को रोकना '

13

आपको बाश में कक्षाओं या वस्तुओं को लागू करने के लिए बहुत अधिक bash कोड की आवश्यकता नहीं है।

कहो, 100 लाइनें।

बैश में साहचर्य सरणियां हैं जिनका उपयोग विरासत, विधियों और गुणों के साथ एक साधारण वस्तु प्रणाली को लागू करने के लिए किया जा सकता है।

तो, आप इस तरह एक वर्ग को परिभाषित कर सकते हैं:

class Queue N=10 add=q_add remove=q_remove

इस कतार का एक उदाहरण इस तरह किया जा सकता है:

class Q:Queue N=100

या

inst Q:Queue N=100

चूंकि कक्षाएं एक सरणी के साथ कार्यान्वित की जाती हैं, इसलिए कक्षा और आवृत्ति वास्तव में समानार्थक शब्द हैं - जैसे जावास्क्रिप्ट में।

इस कतार में आइटम जोड़ना इस तरह किया जा सकता है:

$Q add 1 2 aaa bbb "a string"

किसी चर X में आइटम निकालना इस तरह किया जा सकता है:

$Q remove X

और किसी वस्तु की डंपिंग संरचना इस तरह की जा सकती है:

$Q dump

जो कुछ इस तरह लौटेगा:

Q {
      parent=Queue {
                     parent=ROOT {
                                   this=ROOT
                                   0=dispatch ROOT
                                 }
                     class=Queue
                     N=10
                     add=q_add
                     remove=q_remove
                     0=dispatch Queue
                   }
      class=Q
      N=4
      add=q_add
      remove=q_remove
      0=dispatch Q
      1=
      2=ccc ddd
      3=
      4=
    }

इस तरह एक वर्ग समारोह का उपयोग कर कक्षाएं बनाई जाती हैं:

class(){
    local _name="$1:"                            # append a : to handle case of class with no parent
    printf "$FUNCNAME: %s\n" $_name
    local _this _parent _p _key _val _members
    _this=${_name%%:*}                           # get class name
    _parent=${_name#*:}                          # get parent class name
    _parent=${_parent/:/}                        # remove handy :
    declare -g -A $_this                         # make class storage
    [[ -n $_parent ]] && {                       # copy parent class members into this class
        eval _members=\"\${!$_parent[*]}\"       # get indices of members
        for _key in $_members; do                # inherit members from parent
            eval _val=\"\${$_parent[$_key]}\"    # get parent value
            eval $_this[$_key]=\"$_val\"         # set this member
        done
    }
    shift 1

    # overwrite with specific values for this object
    ROOT_set $_this "$@" "0=dispatch $_this" "parent=${_parent:-ROOT}" "class=$_this"
}

नोट: जब एक नए वर्ग या उदाहरण को परिभाषित करते हैं, तो आप किसी भी सदस्य मान या फ़ंक्शन को ओवरराइड कर सकते हैं।

बैश सहयोगी सरणियों में एक विचित्रता है जो इस काम को बड़े करीने से करती है: $ Q [0]} $ Q के समान है। इसका मतलब है कि हम विधि प्रेषण समारोह को कॉल करने के लिए सरणी नाम का उपयोग कर सकते हैं:

dispatch(){
    local _this=$1 _method=$2 _fn
    shift 2
    _fn="$_this[$_method]"                       # reference to method name
    ${!_fn} $_this "$@"
}

एक पक्ष यह है कि मैं डेटा के लिए [0] का उपयोग नहीं कर सकता हूं इसलिए मेरी कतारें (इस मामले में) सूचकांक = 1 से शुरू होती हैं। वैकल्पिक रूप से मैं "q + 0" जैसे सहयोगी सूचकांकों का उपयोग कर सकता था।

सदस्यों को पाने और सेट करने के लिए आप कुछ इस तरह से कर सकते हैं:

# basic set and get for key-value members
ROOT_set(){                                       # $QOBJ set key=value
    local _this=$1 _exp _key _val
    shift
    for _exp in "$@"; do
        _key=${_exp%%=*}
        _val="${_exp#*=}"
        eval $_this[$_key]=\"$_val\"
    done
}

ROOT_get(){                                       # $QOBJ get var=key
    local _this=$1 _exp _var _key
    shift
    for _exp in "$@"; do
        _var=${_exp%%=*}
        _key=${_exp#*=}
        eval $_var=\"\${$_this[$_key]}\"
    done
}

और एक वस्तु संरचना को डंप करने के लिए , मैंने इसे बनाया:

नोट: यह BOP में OOP के लिए आवश्यक नहीं है, लेकिन यह देखना अच्छा है कि ऑब्जेक्ट कैसे बनाए जाते हैं।

# dump any object
obj_dump(){                                      # obj_dump <object/class name>
    local _this=$1 _j _val _key; local -i _tab=${2:-(${#_this}+2)}  # add 2 for " {"
    _tab+=2                                      # hanging indent from {
    printf "%s {\n" $_this
    eval "_key=\"\${!$_this[*]}\""
    for _j in $_key; do                          # print all members
        eval "_val=\"\${$_this[\$_j]}\""
        case $_j in
            # special treatment for parent
            parent) printf "%*s%s=" $_tab "" $_j; ${!_val} dump $(( _tab+${#_j}+${#_val}+2 ));;
                 *) printf "%*s%s=%s\n" $_tab "" $_j "$_val";;
        esac
    done
    (( _tab-=2 ))
    printf "%*s}\n" $_tab ""
    return 0
}

मेरे ओओपी डिज़ाइन ने वस्तुओं के भीतर वस्तुओं पर विचार नहीं किया है - विरासत में मिला वर्ग को छोड़कर। आप उन्हें अलग से बना सकते हैं, या वर्ग () की तरह एक विशेष निर्माता बना सकते हैं। * obj_dump * आंतरिक कक्षाओं का पता लगाने के लिए उन्हें पुन: मुद्रित करने के लिए संशोधित करने की आवश्यकता होगी।

ओह! और मैं क्लास फंक्शन को सरल बनाने के लिए मैन्युअल रूप से एक ROOT क्लास परिभाषित करता हूं :

declare -gA ROOT=(    \
  [this]=ROOT         \
  [0]="dispatch ROOT" \
  [dump]=obj_dump     \
  [set]="ROOT_set"    \
  [get]="ROOT_get"    \
)

कुछ कतार कार्यों के साथ मैंने कुछ वर्गों को इस तरह परिभाषित किया:

class Queue          \
    in=0 out=0 N=10  \
    dump=obj_dump    \
    add=q_add        \
    empty=q_empty    \
    full=q_full      \
    peek=q_peek      \
    remove=q_remove

class RoughQueue:Queue     \
    N=100                  \
    shove=q_shove          \
    head_drop=q_head_drop

कुछ कतार उदाहरण बनाए और उन्हें काम दिया:

class Q:Queue N=1000
$Q add aaa bbb "ccc ddd"
$Q peek X
$Q remove X
printf "X=%s\n" "$X"
$Q remove X
printf "X=%s\n" "$X"
$Q remove X
printf "X=%s\n" "$X"


class R:RoughQueue N=3
$R shove aa bb cc dd ee ff gg hh ii jj
$R dump

काम कर सकते हैं लेकिन यह बदसूरत है । और पूरी तरह से इसके लिए नहीं bashहै। पाठ को संसाधित करने के लिए शेल लूप का उपयोग न करने के बारे में स्टीफन के उत्तर की याद दिलाता है, विशेष रूप से "वैचारिक" खंड का नेतृत्व करता है जो सी और जैसी भाषाओं के बीच उद्देश्य के अंतर का विवरण देता है bashunix.stackexchange.com/a/169765/135943
वाइल्डकार्ड

1
शायद काम कर जाये? यह काम करता है, लेकिन आपकी बात यह है कि, हालांकि गलत नहीं है, यह अभी नहीं किया गया है। मैंने ओपी प्रश्न का उत्तर भी नहीं दिया, लेकिन यदि बैश टीसी है तो मुझे लगा कि इसे वस्तुओं को संसाधित करने में सक्षम होना चाहिए। और कई ने इसका प्रदर्शन किया है।
14


5

IPython उपयोग करने के लिए आश्चर्यजनक रूप से सुविधाजनक है।

मानक शेल विशेषताएं: नौकरी नियंत्रण, रीडलाइन संपादन और इतिहास, उपनाम, cat ls cdऔर pwdपेजर एकीकरण, किसी भी सिस्टम कमांड को एक !या सक्षम करने के साथ उपसर्ग करके %rehashx, कमांड आउटपुट जो कि अजगर चर के रूप में उपलब्ध अजगर वेरिएबल, पायथन मानों के लिए उपलब्ध है।

पायथन-विशिष्ट: अंतिम आदेशों से पुन: उपयोग, प्रलेखन और स्रोत के लिए त्वरित पहुँच, मॉड्यूल पुनः लोड करना, डीबगर। यदि आप उस में हैं तो कुछ क्लस्टर समर्थन।

उस ने कहा, पायथन में जटिल पाइप नहीं चल रहे हैं; आप पॉज़िक्स शेल का उपयोग कर रहे हैं, बस कुछ गोंद के साथ मूल्यों को और फ्रॉस्ट पास करने के लिए।


2

वहाँ रश जो रूबी और Psh का उपयोग करता है जो पर्ल पर आधारित है।


रश के लिए वेबसाइट अब लाइव नहीं है। यहाँ एक संग्रहीत संस्करण है , और यहाँ github रेपो है । जाहिरा तौर पर इस परियोजना को यहाँ संशोधित किया गया था ( ब्लॉग पोस्ट )।
वाल्डिएरियस

2

jq इस तरह के ऑब्जेक्ट-ओरिएंटेड लेयर के रूप में काफी अच्छी तरह से काम करता है।


2

यह उपयोग करने और सेट-अप करने के लिए थोड़ा सरल है, जिसका नाम है args, आदि। https://github.com/uudruid74/bashTheObjects

मैं एक उदाहरण के साथ अपने उत्तर को अपडेट कर रहा हूं, जो किसी अन्य उत्तर के लिए दिए गए मूल उदाहरणों में से एक का अनुसरण करता है, लेकिन इस वाक्यविन्यास के साथ। उदाहरण कार्यक्रम समान है, लेकिन आप classname साथ सभी चर उपसर्ग की जरूरत नहीं है (यह जानता है इस के रूप में kindof विधि से पता चलता है) मुझे लगता है कि और वाक्य रचना है बहुत आसान!

सबसे पहले, एक वर्ग फ़ाइल। उदाहरण चर के लिए चूक वैकल्पिक हैं और इसका उपयोग केवल तभी किया जाता है जब आप इन मानों को कंस्ट्रक्टर में पास नहीं करते हैं।

class Person
    public show
    public set
    public Name
    public Age
    public Sex
    inst var Name "Saranyan"
    inst var Age 10
    inst var Sex "Male"

Person::Person { :; }
Person::set() { :; }
Person::Name() { println $Name }
Person::Age() { println $Age }
Person::Sex() { println $Sex }
Person::show() {
    Person::Name
    Person::Age
    Person::Sex
}

अब उदाहरण के लिए उपयोग:

#!/bin/bash
source static/oop.lib.sh

import Person

new Person Christy Name:"Christy" Age:21 Sex:"female"
new Person Evan Name:"Evan" Age:41 Sex:"male"

println "$(Evan.Name) is a $(Evan.Sex) aged $(Evan.Age)"
println "$(Christy.Name) is a $(Christy.Sex) aged $(Christy.Age)"
println "Stats for Evan ..."
Evan.show

assert 'kindof Person Evan'
assert '[ $Evan = $Evan ]'
assert 'kindof Person Christy'
assert '[ $Evan = $Christy ]'

टिप्पणियाँ:

  1. वह अंतिम दावा विफल हो जाएगा। उपरोक्त उदाहरण के विपरीत, पुस्तकालय अभी तक ऑब्जेक्ट असाइनमेंट का समर्थन नहीं करता है, लेकिन यह जोड़ना मुश्किल नहीं होगा। मैं इसे आने वाले कंटेनर / पुनरावृत्त समर्थन के साथ अपने TO-DO पर रखूँगा।

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

डिबग स्तर, कंस्ट्रक्टर, डिस्ट्रक्टर्स, सबक्लासिंग और एक बुनियादी प्रतिबिंब प्रणाली भी हैं, और दिखाया गया है कि इको को बदलने के लिए प्रिंट / प्रिंट है (कभी-कभी एक डैश से शुरू होने वाले वेरिएबल को प्रिंट करने का प्रयास करें?)। जीथुब पर उदाहरण यह दिखाता है कि यह एक सीजीआई के रूप में चल रहा है जो कक्षाओं से HTML उत्पन्न करता है।

पुस्तकालय स्वयं (oop.lib.sh) इतना सरल नहीं है (400+ लाइनें, 11K), लेकिन आप इसे शामिल करते हैं और इसे भूल जाते हैं।


2

अब आप लिनक्स पर PowerShell Core Edition स्थापित कर सकते हैं। यह क्रॉस-प्लेटफ़ॉर्म .NET कोर फ्रेमवर्क पर चलता है जिसे Microsoft द्वारा सक्रिय रूप से विकसित किया जा रहा है।


1

अगर कोई वास्तव में सरल रूपरेखा की तुलना में केवल ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग (गुण और तरीके) की मूल बातें चाहता है, तो यह ट्रिक करेगा।

मान लें कि आप वस्तुओं का उपयोग करके "हैलो वर्ल्ड" पाठ प्रदर्शित करना चाहते हैं। सबसे पहले आप एक ऑब्जेक्ट क्लास बनाते हैं जिसमें टेक्स्ट को प्रदर्शित करने के लिए एक संपत्ति होती है और इस टेक्स्ट को सेट करने और उसे प्रदर्शित करने के लिए कुछ तरीके होते हैं। यह दिखाने के लिए कि किसी कक्षा के कई उदाहरण एक साथ कैसे काम कर सकते हैं मैंने पाठ प्रदर्शित करने के लिए दो विधियाँ जोड़ी हैं: एक न्यूलाइन के साथ अंत में और एक उसके बिना।

वर्ग परिभाषा फ़ाइल: EchoClass.class

# Define properties
<<InstanceName>>_EchoString="Default text for <<InstanceName>>"

# Define methods
function <<InstanceName>>_SetEchoString()
{
  <<InstanceName>>_EchoString=$1
}

function <<InstanceName>>_Echo()
{
  # The -ne parameter tells echo not to add a NewLine at the end (No Enter)
  echo -ne "$<<InstanceName>>_EchoString"
}

function <<InstanceName>>_EchoNL()
{
  echo "$<<InstanceName>>_EchoString"
}

कृपया "<<InstanceName>>" शब्द पर ध्यान दें। बाद में इसे क्लास ऑब्जेक्ट के कई उदाहरण बनाने के लिए बदल दिया जाएगा। इससे पहले कि आप एक वस्तु का एक उदाहरण का उपयोग कर सकते हैं आपको एक फ़ंक्शन की आवश्यकता होती है जो वास्तव में इसे बनाता है। चीजों को सरल रखने के लिए यह एक अलग स्क्रिप्ट होगी जिसका नाम है: ObjectFramework.lib

# 1st parameter : object instance name
# 2nd parameter : object instance class

function CreateObject()
{
  local InstanceName=$1
  local ObjectClass=$2
  # We will replace all occurences of the text "<<InstanceName>>" in the class file 
  # to the value of the InstanceName variable and store it in a temporary file
  local SedString='s/<<InstanceName>>/'$InstanceName'/g '$ObjectClass'.class'
  local TmpFile=$ObjectClass'_'$InstanceName'.tmp'
  sed $SedString > $TmpFile

  # The file will contain code which defines variables (properties) and functions (methods)
  # with the name we gave to our object instance via the 1st parameter of this function
  # ... we run this code so the variables and functions are actually defined in runtime
  source "$TmpFile"

  # Than remove the temp file as we don't need it any more
  rm "$TmpFile"
}

तो अब हमारे पास एक क्लास डेफिनिशन फाइल और एक CreateObject फंक्शन है जो इस फाइल की एक कॉपी "<<InstanceName>>" टेक्स्ट के साथ बनाता है जिसे हम चाहते हैं।

आइए हमारी नई वस्तु का उपयोग स्क्रिप्ट में करते हैं: HelloWorld.sh (कृपया ध्यान दें कि HelloWorld.sh को निष्पादन योग्य होना चाहिए। अन्य दो फाइलों की आवश्यकता नहीं है)

# Define the CreateObject function via the lib file we created
source ObjectFramework.lib

# Create two instances of the EchoClass class
CreateObject MyHello EchoClass
CreateObject MyWorld EchoClass

# Call the SetEchoString method of the two objects. In reality these are 
# just two identical functions named differently and setting different
# variables (remember the <<InstanceName>>_EchoString variable?)
MyHello_SetEchoString "Hello "
MyWorld_SetEchoString "World"

# Finally we call the Echo and EchoNL (NewLine) methods
MyHello_Echo
MyWorld_EchoNL

HelloWorld.sh स्क्रिप्ट को चलाने से यह "हैलो वर्ल्ड" (और एक न्यूलाइन जोड़ता है) पाठ प्रदर्शित करता है। कोई भी इस परिणाम से बहुत प्रभावित नहीं होगा, लेकिन हम जानेंगे कि यह इतना सरल नहीं है जितना यह दिखता है :)

हैप्पी कोडिंग!


सरल चीजों को जटिल बनाने की अपेक्षा जटिल चीजों को सरल बनाना बेहतर है।
वाइल्डकार्ड

1

यह पायथन में स्थित एक वस्तु उन्मुख शेल है, लेकिन इसमें गोलंग के करीब एक सिंटेक्स है: https://github.com/alexst07/shell-plus-plus

उदाहरण के लिए, पकड़ने का प्रयास करें:

try {
  git clone git@github.com:alexst07/shell-plus-plus.git
} catch InvalidCmdException as ex {
  print("git not installed [msg: ", ex, "]")
}

वर्ग और ऑपरेटर अधिभार:

class Complex {
  func __init__(r, i) {
    this.r = r
    this.i = i
  }

  func __add__(n) {
    return Complex(n.r + this.r, n.i + this.i)
  }

  func __sub__(n) {
    return Complex(n.r - this.r, n.i - this.i)
  }

  func __print__() {
    return string(this.r) + " + " + string(this.i) + "i"
  }
}

c1 = Complex(2, 3)
c2 = Complex(1, 2)
c = c1 + c2

print(c)

और आप इसी तरह के बैश का उपयोग कर सकते हैं:

echo "Test" | cat # simple pipeline
ls src* | grep -e "test" # using glob

# using variables content as command
cip = "ipconfig"
cgrep = ["grep", "-e", "10\..*"]
${cip} | $@{cgrep} # pass an array to command

0

अब, अधिकांश समय आप किन वस्तुओं के साथ काम कर रहे हैं? यह फाइलें / निर्देशिकाएं, प्रक्रियाएं और उनकी सहभागिता है। तो इसे पसंद करना चाहिए f1.editया कुछ और currentFile=f1.c ; .edit ; .compile ; .run। या d1.search(filename='*.c' string='int \*')। या फिर p1.stop, p1.bg। एक ओशेल की मेरी समझ है।


0
## implemantion of base class
function Class()
{
    base=${FUNCNAME}
    this=${1}
    Class_setCUUID $this
    for method in $(compgen -A function)
    do
        export ${method/#$base\_/$this\_}="${method} ${this}"
    done

}

function copyCUUID()
{
        export ${2}_CUUID=$(echo $(eval "echo \$${1}_CUUID"))

}

function Class_setCUUID()
{
        export ${1}_CUUID=$(uuid)
}

function Class_getCUUID()
{
        echo $(eval "echo \$${2}_CUUID")
}


function Class_setProperty()
{
        export ${1}_${2}=${3}
}

function Class_getProperty()
{
        echo $(eval "echo \$${1}_${2}")
}

function Class_Method()
{
        echo "function ${1}_${2}()
        {
        echo null
        }
        " > /tmp/t.func
        . /tmp/t.func
        rm /tmp/t.func


}

function Class_setMethod()
{
        export ${1}_${2}=${1}_${2}
}


function Class_getMethod()
{
        $(eval "echo \$${1}_${2}")
}


function Class_equals()
{
        base="Class"
        this=${2}

    copyCUUID ${1} ${2}
    for method in $(compgen -A function)
    do
        export ${method/#$base\_/$this\_}="${method} ${1}"
    done


}

बस संदर्भ के आधार पर बैश करने के लिए oo अवधारणाओं को प्रस्तुत करने की कोशिश की गई http://hipersayanx.blogspot.in/2012/12/object-oriented-programming-in-bash.html

source ./oobash

Class person
$person_setProperty Name "Saranyan"
$person_setProperty Age 10
$person_setProperty Sex "Male"
function person_show()
{
$person_getProperty Name
$person_getProperty Age
$person_getProperty Sex
}
$person_setMethod show

$person_equals person1
$person1_getMethod show
$person1_equals person3
$person_getCUUID person
$person_getCUUID person1
$person_getCUUID person3

0

छोटे उत्तर के लिए क्षमा करें, लेकिन यहाँ जाता है।

हिपर्सायनेक्स ने बैश में एक लेख ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग बनाया है । असल में वह उच्च लानत $FUNCNAME, function, compgen, और exportपास के रूप में बनाने के लिए एक पार्टी में प्राप्त कर सकते हैं OOP करने के लिए।

कूल भाग यह अच्छी तरह से काम करता है और एक वर्ग बनाने के लिए बॉयलर की कुछ लाइनों की आवश्यकता होती है।

बुनियादी भागों की जरूरत है:

ClassName() {
# A pointer to this Class. (2)
base=$FUNCNAME
this=$1

# Inherited classes (optional).
export ${this}_inherits="Class1 Class2 Class3" # (3.1)
 for class in $(eval "echo \$${this}_inherits")
do
    for property in $(compgen -A variable ${class}_)
    do
        export ${property/#$class\_/$this\_}="${property}" # (3.2)
    done

    for method in $(compgen -A function ${class}_)
    do
        export ${method/#$class\_/$this\_}="${method} ${this}"
    done
done

# Declare Properties.
export ${this}_x=$2
export ${this}_y=$3
export ${this}_z=$4

# Declare methods.
for method in $(compgen -A function); do
    export ${method/#$base\_/$this\_}="${method} ${this}"
done
}

function ClassName_MethodName()
{
#base is where the magic happens, its what holds the class name
base=$(expr "$FUNCNAME" : '\([a-zA-Z][a-zA-Z0-9]*\)')
this=$1

x=$(eval "echo \$${this}_x")

echo "$this ($x)"
}

उपयोग:

# Create a new Class Instance
ClassName 'instanceName' $param1 $param2

$instanceName_method

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

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


0

मैं GitHub पर एक फ़ंक्शन विकसित कर रहा हूं जो एक HashMap ऑब्जेक्ट , shell_map की तरह काम करता है ।

" HashMap उदाहरण " बनाने के लिए यह फ़ंक्शन विभिन्न नामों के तहत स्वयं की प्रतियां बनाने में सक्षम है। प्रत्येक नई फ़ंक्शन कॉपी में एक अलग $ FUNCNAME चर होगा। $ FUNCNAME का उपयोग तब प्रत्येक मैप उदाहरण के लिए नाम स्थान बनाने के लिए किया जाता है।

मैप कुंजियाँ वैश्विक चर हैं, $ FUNCNAME_DATA_ $ कुंजी के रूप में, जहाँ $ KEY मानचित्र में जोड़ी गई कुंजी है। ये चर गतिशील चर हैं

Bellow मैं इसका एक सरलीकृत संस्करण डालूँगा ताकि आप उदाहरण के रूप में उपयोग कर सकें।

#!/bin/bash

shell_map () {
    local METHOD="$1"

    case $METHOD in
    new)
        local NEW_MAP="$2"

        # loads shell_map function declaration
        test -n "$(declare -f shell_map)" || return

        # declares in the Global Scope a copy of shell_map, under a new name.
        eval "${_/shell_map/$2}"
    ;;
    put)
        local KEY="$2"  
        local VALUE="$3"

        # declares a variable in the global scope
        eval ${FUNCNAME}_DATA_${KEY}='$VALUE'
    ;;
    get)
        local KEY="$2"
        local VALUE="${FUNCNAME}_DATA_${KEY}"
        echo "${!VALUE}"
    ;;
    keys)
        declare | grep -Po "(?<=${FUNCNAME}_DATA_)\w+((?=\=))"
    ;;
    name)
        echo $FUNCNAME
    ;;
    contains_key)
        local KEY="$2"
        compgen -v ${FUNCNAME}_DATA_${KEY} > /dev/null && return 0 || return 1
    ;;
    clear_all)
        while read var; do  
            unset $var
        done < <(compgen -v ${FUNCNAME}_DATA_)
    ;;
    remove)
        local KEY="$2"
        unset ${FUNCNAME}_DATA_${KEY}
    ;;
    size)
        compgen -v ${FUNCNAME}_DATA_${KEY} | wc -l
    ;;
    *)
        echo "unsupported operation '$1'."
        return 1
    ;;
    esac
}

उपयोग:

shell_map new credit
credit put Mary 100
credit put John 200
for customer in `credit keys`; do 
    value=`credit get $customer`       
    echo "customer $customer has $value"
done
credit contains "Mary" && echo "Mary has credit!"

आपको गलतफहमी होने लगती है कि कमांड प्रतिस्थापन कैसे काम करता है। यह backticks के भीतर समाहित कमांड के आउटपुट के साथ प्रतिस्थापित किया जाता है, रिटर्न स्टेटस के साथ प्रतिस्थापित नहीं किया जाता है । दूसरे शब्दों में आपका कोड वह नहीं करता है जो आपको लगता है कि वह करता है।
वाइल्डकार्ड

अहा। तुम सही हो। मैं क्षमाप्रार्थी हूं। हालाँकि, इसके carp "Some error message"; returnबजाय इसका उपयोग करना अधिक स्पष्ट होगा ।
वाइल्डकार्ड

या [ -z "$KEY" ] && { carp "some message"; return;} किसी सब-उप की आवश्यकता नहीं है। लेकिन वास्तव में एक if ... elif ... elif ... else ... fiनिर्माण के लिए एक वास्तविक उम्मीदवार की तरह दिखता है - जो अक्सर सबसे अच्छा विकल्प नहीं होता है, लेकिन शायद यहाँ है। :) (या शायद एक मामला स्विच।)
Wildcard

@Wildcard मैंने जवाब संपादित किया। अब कार्प और बैकटिक्स के बारे में हमारी चर्चा का कोई मतलब नहीं है। चलो इस वार्तालाप को हटा दें?
ब्रूनो नेग्रो ज़ीका

0

प्लंबम एक पायथन जैसी शेल भाषा है। यह पायथन के साथ सिंटैक्स की तरह शेल को पैकेज करता है जो अनुभव को ऑब्जेक्ट-ओरिएंटेड बनाता है।

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