क्या कोई कार्यात्मक-जैसा यूनिक्स शेल है?


18

मैं (वास्तव में) कार्यात्मक प्रोग्रामिंग के लिए नौसिखिया (वास्तव में केवल अजगर के साथ इसका संपर्क था) लेकिन एक शेल वातावरण में कुछ सूची-गहन कार्यों के लिए एक अच्छा दृष्टिकोण प्रतीत होता है।

मुझे ऐसा कुछ करना अच्छा लगेगा:

$ [ git clone $host/$repo for repo in repo1 repo2 repo3 ]

क्या इस तरह की सुविधा के साथ कोई यूनिक्स शेल है? या हो सकता है कि कुछ सुविधा आसान शेल एक्सेस (कमांड, एनवी / वर्स, रीडलाइन आदि ...) से अजगर के भीतर जाने की अनुमति देती है (यह विचार है कि अजगर को इंटरएक्टिव इंटरप्रेटर का उपयोग बैश में बदलने के लिए किया जाता है)।

संपादित करें:

शायद एक तुलनात्मक उदाहरण स्पष्ट होगा। मान लीजिए कि मेरे पास dir / file से बनी एक सूची है :

$ FILES=( build/project.rpm build/project.src.rpm )

और मैं वास्तव में एक सरल कार्य करना चाहता हूं: सभी फाइलों को कॉपी करें / इसे सिस्टम में स्थापित करें (यह एक बिल्ड प्रक्रिया का हिस्सा है):

बैश का उपयोग करना:

$ cp $ {फाइलें [*]} dist /
$ cd dist && rpm -Uvh $ (f में $ {फाइलें [*]} के लिए, क्या $ f? किया है?);

"पायथोनिक शेल" दृष्टिकोण का उपयोग करना (सावधानी: यह काल्पनिक कोड है):

$ cp [os.path.join ('dist', os.path.basename (फ़ाइल)) FILES में फ़ाइल के लिए] 'dist'

क्या आप अंतर देख सकते हैं ? कि मैं किस बारे में बात कर रहा हूँ इस तरह के सामान के निर्माण के साथ एक खोल को बाहर कैसे नहीं किया जा सकता है? शेल में सूचियों को संभालना एक वास्तविक दर्द है, यहां तक ​​कि इसका इतना सामान्य कार्य है: फाइलों की सूची, पीआईडी ​​की सूची, सब कुछ की सूची।

और वास्तव में, वास्तव में, महत्वपूर्ण बिंदु: वाक्यविन्यास / उपकरण / सुविधाओं का उपयोग करना हर कोई पहले से जानता है: श और अजगर।

IPython सीम अच्छी दिशा में है, लेकिन यह फूला हुआ है: यदि var नाम '$' से शुरू होता है, तो यह ऐसा करता है, यदि '$$' ऐसा करता है। यह सिंटैक्स "प्राकृतिक" नहीं है, इतने सारे नियम और "वर्कअराउंड" ( [ ln.upper() for ln in !ls ] -> सिंटैक्स त्रुटि)


कुछ हद तक संबंधित: github.com/amoffat/pbs
जोश ली


4
कार्यात्मक प्रोग्रामिंग में सूची की समझ से थोड़ा अधिक है। यदि आपका मुख्य ध्यान कार्यात्मक कोड लिख रहा है, तो मैं एक उदाहरण के रूप में अजगर नहीं ले सकता।
pqnet

जवाबों:


10

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

अपडेट करें :

मैंने बस खुद को स्थापित किया और इसे आजमाया। ऐसा प्रतीत होता है कि scsh वास्तव में उपयोगी इंटरैक्टिव खोल की तुलना में एक इंटरैक्टिव स्कीम दुभाषिया और स्क्रिप्टिंग भाषा का अधिक है। आप सिर्फ टाइप नहीं कर सकते

echo hello

वाक्य-विन्यास प्रतीत होता है

(run (echo hello))

और इसे खोजने के लिए Googling के कई मिनट लगे। पहला उदाहरण यहाँ है:

gunzip < paper.tex.gz | detex | spell | lpr -Ppulp &

जो अनुवाद करता है:

(& (| (gunzip) (detex) (spell) (lpr -Ppulp)) (< paper.tex.gz))

लेकिन यह आपको नहीं बताता है कि एक साधारण शेल कमांड कैसे चलाना है ।

यह FAQ प्रविष्टि कहती है:

4.6 क्या मैं एक इंटरैक्टिव शेल के रूप में scsh का उपयोग कर सकता हूं?

ठीक है, तकनीकी रूप से आप कर सकते हैं: बस "स्केश" कमांड को चलाएं और आप स्कीम के सभी उपलब्ध कार्यों के साथ 48 सत्र में प्रवेश करेंगे। हालांकि, यह निश्चित रूप से इंटरेक्टिव काम के लिए उपयुक्त नहीं है: कोई कमांड-लाइन संपादन नहीं है, कोई कमांड-लाइन इतिहास नहीं है, कोई फ़ाइल / फ़ंक्शन नाम पूरा नहीं है, कोई ट्रिक सिंटैक्स नहीं है, आदि।

इन समस्याओं को कम करने के लिए, मार्टिन गैसबाइक्लर और एरिक कन्नुएल ने कमांडर एस लिखा है, जो स्कैश के शीर्ष पर चलता है और एक आरामदायक इंटरैक्टिव वातावरण प्रदान करता है। इसकी एक उपन्यास विशेषता यह है कि यह कई यूनिक्स कमांड के आउटपुट को समझ सकता है, और उपयोगकर्ता को इसे उपयोगी तरीकों से ब्राउज़ और हेरफेर करने की अनुमति देता है। कमांडर एस के बारे में अधिक जानकारी का वर्णन करने वाले कागज में पाया जा सकता है: http://www.deinprogramm.de/scheme-2005/05-knauel/05-knauel.pdf कमांडर एस को कैसे प्राप्त करें और कैसे स्थापित करें, इसके बारे में निर्देश। scsh वेब साइट: http://www.scsh.net/resources/commander-s.html

तो शायद यही असली जवाब है।


7

सीधे सवाल का जवाब देने की श्रेणी में, ईएस शेल है जो बश और ज़ीश आदि के लिए कार्यात्मक प्रतिस्थापन के रूप में अभिप्रेत है।

दूसरे, आपको अधिक कार्यात्मक मानक शेल लिखने में मदद करने की श्रेणी में, पाइपमेल तकनीक सीखने पर विचार करें:

who | while read username 
do
  cat <<EOF | grep $username
nic
mark
norman
keith
EOF
done | while read username
do
  echo "you have an answer on superuser.com" | mail -s "well done" $username
done

पहला जबकि लूप एक फंक्शनल है keep(केवल लूप से बाहर आने वाले नॉन-न्यूल वैल्यू पर पास) और दूसरा एक है each(केवल साइड इफेक्ट के लिए मैप)।

यह गोले में fp के लिए एक जबरदस्त बढ़ावा है।

एक शेल में अधिक fp शैली में कई चीजों को व्यक्त करना संभव है, यह उतना आसान नहीं है जितना कि हो सकता है। ऐसा लगता है कि बेहतर गोले बनाने में बहुत रुचि नहीं है, भले ही हम सभी उन्हें इस तरह का उपयोग करते हैं।


6

मानक बॉर्न शैली गोले ( sh, bash, ksh, आदि) पहले से ही आप करते हैं:

for repo in repo1 repo2 repo3 ; do git clone $host/$repo ; done

(पहले doऔर बाद में अर्धविराम की आवश्यकता पर ध्यान दें done) इसके अलावा, bashऔर अन्य गोले, यदि $repoकेवल एक बार कमांड में दिखाई देता है , तो आप यह लिख सकते हैं:

git clone $host/{repo1,repo2,repo3}

यकीन है, और मैं इसे बहुत उपयोग करते हैं। लेकिन अन्य सामान के बारे में क्या, जैसे मेमने का कार्य?

8
git clone $host/{repo1,repo2,repo3}forलूप के समान काम नहीं करता है ; यह git cloneतीन तर्कों के साथ एक बार आमंत्रित करता है। तथ्य यह है कि अनिवार्य रूप से एक ही बात करता है कि कैसे git cloneकाम करता है की एक कलाकृति है ; यह आवश्यक रूप से अन्य आदेशों पर लागू नहीं होता है। (तुलना echo foo bar bazकरने के लिए echo foo; echo bar; echo baz, उदाहरण के लिए।)
कीथ थॉम्पसन

@caruccio का उपयोग आप FUN=eval 'git clone '"$host"'$0 एक लैम्ब्डा को परिभाषित करने के लिए कर सकते हैंfor repo in repo{1,2,3} ; do $FUN $repo ; done
pqnet

सबसे बड़ा मुद्दा यह है कि यूनिक्स टूल्स में अक्सर साइड इफेक्ट्स होते हैं (जैसे कि फाइलों को लिखना), इसलिए आप अक्सर उन्हें ऐसे नहीं लिख सकते हैं जैसे आप एक कार्यात्मक भाषा में करना चाहते हैं।
वेबर 2

2

स्कीम, एसएलएस, वास्तव में अच्छा है।

कीथ थॉम्पसन नोट्स के रूप में, यह एक इंटरैक्टिव शेल के रूप में उपयोगी नहीं है (हालांकि कमांडर एस एक दिलचस्प प्रयोग की तरह दिखता है)। इसके बजाय, यह संदर्भों के लिए एक उत्कृष्ट प्रोग्रामिंग भाषा है, जहां सभी POSIX बाइंडिंग उपयोगी हैं - जिसमें ऐसे मामले शामिल हैं जहां आप अन्य यूनिक्स एप्लिकेशन को कॉल करना चाहते हैं। कुछ दर्जन से अधिक लाइनों की एक शेल स्क्रिप्ट हमेशा हैक की तरह महसूस करेगी , चाहे आप कितने भी बड़े करीने से लिखें sh; इसके विपरीत, आपको scsh का उपयोग करके महत्वपूर्ण कार्यक्रमों को लिखने से कोई रोक नहीं है।

scsh बहुत कॉम्पैक्ट नहीं है (संक्षिप्तता श-परिवार भाषाओं की ताकत और कमजोरी दोनों है), लेकिन यह शक्तिशाली है।

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

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

कोई अर्थपूर्ण अर्थ नहीं है जिसमें श-शैली के गोले कार्यात्मक हैं, और पायथन केवल सीमांत अर्थों में कार्यात्मक है कि इसमें एक लंबोदर फ़ंक्शन है।


2

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

हम आम तौर पर भाषाओं को एक विशेष उद्देश्य के लिए डिजाइन करके अभिव्यक्त करते हैं, जैसे कि शेल या डीएसएल जैसे आर, मेपल, आदि। और आप ज्यादातर सामान्य प्रयोजन भाषाओं जैसे सी, सी ++, जावा, आदि में अपेक्षाकृत कम अभिव्यंजना पाते हैं।

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

योजना वह अर्थपूर्ण नहीं है, जिसमें एक बार आप सभी कोष्ठकों के कारण DLS का निर्माण कर सकते हैं।

हालांकि बहुत ही स्पष्टता के साथ हास्केल जैसी कार्यात्मक भाषाएं हैं और डीएसएल के निर्माण के लिए एक महान क्षमता है। हास्केल पर एक शेल बनाने के दिलचस्प प्रयास कछुए और आश्रय हैं

व्यवहार में, हास्केल शक्तिशाली लेकिन प्रतिबंधात्मक प्रकार की प्रणाली के कारण प्रयासों के साथ एक सीखने की अवस्था है, लेकिन वे काफी वादा दिखाते हैं।


1

सबसे पहले, आपको "${files[@]}"आपके पास हर जगह का उपयोग करना चाहिए ${files[*]}। अन्यथा रिक्त स्थान आपको गड़बड़ कर देंगे।

शेल पहले से ही बहुत कार्यात्मक है; यदि आप लाइनों के पाठ उत्पादन किया जा रहा है सूचियों के मामले में लगता है, तो grepहै filter, xargsहै mapपाइप्स बहुत कार्य कर रहे हैं, आदि।

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

मुझे समझ में नहीं आता है कि आप cp [ os.path.join('dist', os.path.basename(file)) for file in FILES ] 'dist'बेहतर क्यों पाते हैं cp "${FILES[@]}" dist। उत्तरार्द्ध बहुत कम टाइपिंग है।


0

यह जा रहा है "कार्यात्मक" के बारे में पता है, लेकिन नहीं है वहाँ भी आर सी , जो scsh कागज का उल्लेख है। यह एक पूर्ववर्ती से बचने के लिए है।

लिनक्स टकसाल (और शायद डेबियन, उबंटू ...) पर आप इसके साथ कोशिश कर सकते हैं

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