मुझे "के लिए" एक ही पंक्ति में "करने" की आवश्यकता क्यों है?


28

1. सारांश

मुझे समझ नहीं आता, मुझे E010 बेसहेट नियम की आवश्यकता क्यों है ।


2. विवरण

मैं फाइलिंग के लिए बेसहेट का उपयोग करता हूं.sh । E010 नियम:

कर के रूप में एक ही लाइन पर नहीं के लिए

for bashate:

  • सही बात:

    #!/bin/bash
    for f in bash/*.sh; do
        sashacommand "$f"
    done
  • त्रुटि:

    #!/bin/bash
    for f in bash/*.sh
        do sashacommand "$f"
    done

क्या कोई मान्य तर्क है, जिसकी मुझे आवश्यकता है forऔर doउसी पंक्ति में है?


3. उपयोगी नहीं है

मुझे अपने प्रश्न का उत्तर नहीं मिल रहा है:

  1. गूगल
  2. सर्वोत्तम कोडिंग प्रथाओं के बारे में लेख ( उदाहरण )
  3. आधारभूत प्रलेखन । मुझे केवल यही मिला :

    नियमों का एक सेट जो नियंत्रण ब्लॉकों में चीजों को लगातार रखने में मदद करता है। इन्हें लंबी लाइनों पर अनदेखा किया जाता है, जिसमें निरंतरता होती है, क्योंकि "दिलचस्प" की तरह यह अनियंत्रित है


3
इंडेंट doनिश्चित रूप से थोड़ा असामान्य है, लेकिन for ... \ndo\n<indent>body...बेहद सामान्य है और मैं इससे भी अधिक अनुमान लगाऊंगा for ... ; do। क्या इसके बारे में भी शिकायत है?
माइकल होमर

20
bashateएक स्टाइल चेकर है। शैलियाँ स्वाभाविक रूप से व्यक्तिपरक हैं। अगर आपको यह आर्टवर्क पसंद नहीं है तो इसे इस्तेमाल न करें। आपको इसके बजाय गोले की तरह एक वाक्यविन्यास / बग चेकर पर विचार करना चाहिए ।
meuh

@meuh, धन्यवाद, मैं पहले से ही शेलचेक का उपयोग करता हूं। मेरे सवाल: E010- केवल शैली नियम या कुछ मामलों मैं की जरूरत है के लिए और कर न केवल शैली कारणों से एक ही पंक्ति में।
Саша нерных

10
शेल में एक ही लाइन पर होने और करने के लिए एक सिंटैक्टिक बाध्यता नहीं है ।
मयूह

1
@ Саша Черных यह असामान्य नहीं है, इसके द्वारा ही इंडेंटेशन नहीं है do। यह सी की तरह एक ifही लाइन पर खुलने वाले ब्रेस को जोड़ने और कोड की तरह भाषा में इंडेंट करने के लिए है। एक अन्य उदाहरण, अगर अजगर ने इसकी अनुमति दी, तो अगली लाइन पर :एक ifइंडेंट लगाया जाएगा और उसी लाइन पर कोड को जोड़ा जाएगा। यह शरीर में अतिरिक्त लाइनों के साथ इसे अलग बनाने जा रहा है।
जोएल

जवाबों:


60

Syntactically, निम्नलिखित दो कोड स्निपेट सही और समतुल्य हैं:

for f in bash/*.sh; do
    sashacommand "$f"
done
for f in bash/*.sh
    do sashacommand "$f"
done

उत्तरार्द्ध को संभवतः पढ़ने के लिए कठिन कहा जा सकता doहै क्योंकि लूप के शरीर में थोड़ी सी आज्ञा का पालन होता है। यदि लूप में कई कमांड होते हैं और अगली कमांड एक नई लाइन पर होती है, तो ऑबफैक्शन को और हाइलाइट किया जाएगा:

for f in *
    do cmd1
    cmd2
done

... लेकिन इसे "त्रुटि" के रूप में चिह्नित करने के लिए एक उद्देश्य सच्चाई के बजाय IMHO किसी की व्यक्तिगत राय है।

सामान्य तौर पर, लगभग किसी भी ;एक नई पंक्ति द्वारा प्रतिस्थापित किया जा सकता है। दोनों ;और न्यूलाइन कमांड टर्मिनेटर हैं। doएक कीवर्ड है जिसका अर्थ है "यहां इस प्रकार किया जाना चाहिए (इस forलूप में)"।

for f in *; do ...; done

के समान है

for f in *
do
   ...
done

और जैसे

for f in *; do
   ...
done

एक से अधिक का उपयोग करने का कारण पठनीयता और स्थानीय / व्यक्तिगत शैली सम्मेलनों है।


निजी राय:

लूप हेडर में जो बहुत लंबे होते हैं , मुझे लगता है कि यह doएक नई लाइन पर डालने के लिए समझ में आ सकता है , जैसे कि

for i in animals people houses thoughts basketballs bees
do
    ...
done

या

for i in        \
    animals     \
    people      \
    houses      \
    thoughts    \
    basketballs \
    bees
do
    ...
done

thenएक ifबयान में वही जाता है ।

लेकिन फिर, यह किसी की व्यक्तिगत शैली वरीयताओं के लिए, या जो भी कोडिंग शैली किसी की टीम / परियोजना का उपयोग कर रहा है के लिए नीचे आता है।


आप कहते हैं कि "लूप हेडर में जो बहुत लंबे होते हैं, यह एक नई लाइन पर डालने के लिए समझ में आता है"। क्या आप इसके लिए कोई कारण बता सकते हैं? यह देखते हुए कि शीर्ष लेख का पालन किया जाना चाहिए do, मुझे कोई कारण नहीं दिखता कि इसे अगली पंक्ति में रखने से पठनीयता में मदद मिलेगी।
कोनराड रुडोल्फ

3
@KonradRudolph मेरा टर्मिनल 80 वर्ण चौड़ा है। यदि सूची में लपेटता है, तो मैं इसे निरंतर लाइनों का एक सेट बना दूंगा (जैसा कि मेरे अंतिम उदाहरण में है), यदि यह लगभग लपेटता है, तो मैं do(या then) अपने दम पर एक लाइन पर रखूंगा (दूसरे से अंतिम उदाहरण के रूप में)। यह सब व्यक्तिगत प्राथमिकताओं के साथ है। मुझे अधिक लंबी लाइनें पसंद नहीं हैं, आंशिक रूप से क्योंकि मेरा टर्मिनल "केवल" 80 वर्ण चौड़ा है, और आंशिक रूप से क्योंकि मुझे लगता है कि यह अस्वच्छ दिखता है। मुझे त्रुटियों के लिए बहुत लंबी लाइनों को पार्स करना भी मुश्किल है।
Kusalananda

1
यह इंगित करना अनावश्यक है कि यह राय है। bashate एक स्टाइल गाइड है, इसलिए यह स्वाभाविक रूप से राय पर आधारित है।
बरमार

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

2
@mtraceur राइट, मैं व्यक्तिगत प्राथमिकताओं पर सवाल नहीं उठा रहा हूँ। लेकिन ध्यान रखें कि आपके द्वारा बोली जाने वाली पठनीयता स्तंभ सीमा कोड पर लागू नहीं होती है। यह केवल गद्य पर लागू होता है। नेत्र पठन कोड रीडिंग के लिए मौलिक रूप से भिन्न है, इसलिए उन अध्ययनों के प्रमाण यहां लागू नहीं हैं। और ऐतिहासिक कारणों का उपयोग करने के लिए जो अब तर्क के रूप में लागू नहीं होते हैं, ठीक है, हमने पिछले 8.3 फ़ाइलनामों का भी उपयोग किया है।
कोनराड रुडोल्फ

28

ध्यान दें कि यह पृष्ठ के शीर्ष पर क्या कहता है:

bashate: bash लिपियों के लिए एक pep8 बराबर

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

यह एक ही चर्चा है कि {सी कोड को कहां रखा जाए ifया एक whileब्लॉक (या इस तरह) शुरू करते समय ।


प्रलेखन में नीचे कुछ पंक्तियाँ, एक और दिलचस्प नियम है:

E020: फ़ंक्शन घोषणा प्रारूप में नहीं ^function name {$

मुझे लगता है कि यहाँ बिंदु यह है कि उस शैली गाइड के लेखक को लगता है कि functionपाठक के लिए फ़ंक्शन की घोषणा को पहचानने के लिए कीवर्ड का उपयोग करना आवश्यक है। हालांकि, एक फ़ंक्शन को परिभाषित करने function fooका एक गैर-मानक तरीका है: मानक तरीका है foo()। दोनों (बाश में) के बीच एकमात्र अंतर यह है कि दूसरे को मानक शेल में पोर्ट करना कठिन है, जैसे /bin/shडेबियन या उबंटू में।

तो, मैं सुझाव दूंगा कि नमक के दाने या तीन के साथ कोई भी और सभी स्टाइल गाइड लें, और अपने लिए निर्णय लें कि सबसे अच्छी शैली क्या है। एक अच्छा स्टाइल-चेकर कुछ चेकों को निष्क्रिय करने की अनुमति देता है (बेसहेट को bashate -i E010,E011उन दो चेकों को अनदेखा करना पड़ता है ।) एक उत्कृष्ट स्टाइल-चेकर आपको परीक्षणों को संशोधित करने की अनुमति देगा, जैसे कि E020 के विपरीत की जाँच करने के लिए, यहाँ।


12

TL; DR: आप की जरूरत नहीं है। यह सिर्फ कुछ दोस्त की राय है।

कई अन्य लोगों की तरह, मैं भी forदशकों से इस तरह से लिख रहा हूं :

for F in arg1 arg2 arg*
do
    somecommand "$F"
done

यह लेआउट इस तथ्य को उजागर करता है कि do ... doneलूप बॉडी के चारों ओर, सी-जैसी भाषाओं में घुंघराले ब्रेसिज़ की तरह है, और लूप निर्माण के घटकों को अलग करने के लिए न्यूलाइन की अनुमति देता है।

निश्चित रूप से धार्मिक युद्ध हैं जहां घुंघराले ब्रेसिज़ को भी रखना है, इसलिए आप कह सकते हैं कि जूरी अभी भी इस पर बाहर है। IMHO, यह स्पष्ट रूप से है कि यह कैसे काम करने के लिए डिज़ाइन किया गया था; बॉर्न को मैच्योर डेलीमेट्स, सीएफ के शौकीन थे।if ... fi, case ... esacऔर छोटे संस्करण में अर्धविराम की आवश्यकता बताती है कि आप इसे मूल रूप से डिज़ाइन किए गए से छोटा बना रहे हैं। कुछ गलत नहीं है उसके साथ; प्रौद्योगिकी की प्रगति और बहुत सी चीजें जो एक समय में एक अच्छे विचार की तरह प्रतीत होती थीं, अब उन पर आधारित हैं, जैसे goto। लेकिन जब तक पूरा शेल-स्क्रिप्टिंग समुदाय bashateलेखक (एस) की वरीयताओं को नहीं अपनाता, तब तक आपको एक काम करने की ज़रूरत नहीं है।


3
यह Algol 68 से आता है , और आदि से fiमेल खाता है । केवल एक लूप के समाप्त नहीं होने का कारण यह है कि यह एक मौजूदा मानक उपयोगिता का नाम है। देखें en.wikipedia.org/wiki/ALGOL_68C#Algol_68C_and_Unixifesacfordoodod
Kusalananda

1
Pascal (जो उपयोग करता है begin ... endआदि) सहित Algol परिवार की अन्य भाषाओं में भी राइट और कीवर्ड-सीमांकित ब्लॉक का उपयोग किया गया था ।
एलेक्सिस

2
के बारे में कहानी नहीं सुना था od, यह हास्यास्पद है ... (हालांकि, क्यों नहीं बस के साथ छोरों के लिए rof, फिर?)
एलेक्सिस

2
@alexis खैर, जैसे कुसलानंद ने कहा, यह अल्गोल 68 से आता है, यह महत्वपूर्ण बिंदु है। मूल बॉर्न शेल के निर्माता स्टीफन बॉर्न उस भाषा से काफी प्रभावित थे, और इसीलिए वह उस वाक्य रचना से चिपक गए थे। जब वह सी में लिख रहा था तब भी बोर्न शेल के लिए स्रोत कोड देखें: minnie.tuhs.org//cgi-bin/utree.pl?file=V7/usr/src/cmd/sh/mac.h ओह, और रास्ता, BEGINऔर ENDवहाँ भी परिभाषित कर रहे हैं।
सर्गी कोलोडियाज़नी

1
यह पूरी प्रारूपण शैली भी अल्गोल 68 से आती है। इसका FORऔर DOभी अलग-अलग लाइनों पर होगा, सम्मेलन द्वारा, सिवाय जब पूरा लूप एक लाइन पर आसानी से फिट होगा।
रीइनियरिएपोस्ट

3

मुझे आश्चर्य है कि किसी ने भी इस वैध और पोर्टेबल सिंटैक्स का उल्लेख नहीं किया है:

set alfa bravo charlie
for q do
  echo "$q"
done

ध्यान से देखें forऔर doअर्धविराम के बिना एक ही लाइन पर हैं। परिणाम:

alfa
bravo
charlie

मैं इस अस्पष्ट (लेकिन कुछ मामलों में स्वच्छ और पोर्टेबल शेल कोड के लिए महत्वपूर्ण) सिंटैक्स का उल्लेख करने के लिए इस उत्तर का अनुमोदन करता हूं, हालांकि यह लोगों को स्पष्ट रूप से समझाने लायक है कि यह स्थितिगत मापदंडों को स्पष्ट करता है, और इसके अलावा, मुझे यह उल्लेख करने के लिए मजबूर होना चाहिए। एकमात्र "वास्तव में पोर्टेबल (टीएम)" रूप वह है जहां अलग-अलग रेखाएं हैं for qऔर do(इस उदाहरण में प्रपत्र कुछ दशक पहले मूल अल्मक्विश शेल पर ash) असमर्थित था ( ): in-ulm.de/~mascheck/various/ bourne_args / # एंडनोट )
mtraceur

जबकि इस उत्तर में उदाहरण मेरे लिए काम करता है, इसे ओपी के प्रश्न में उदाहरण पर लागू करने से काम नहीं चलता है ।
स्क्रिप्बलमैकर

3

कई अच्छे जवाब यहाँ। हमेशा नमक के एक दाने के साथ स्टाइल गाइड लें, और IMHO और अनुभव, कभी-कभी थोड़ा-से-मध्यम हो किसी भी समुदाय के बारे में चिंतित हैं जो शैली में आने पर अत्यधिक हठधर्मिता से ग्रस्त है। यह लगभग वैसा ही है जैसा कि वे मानते हैं कि जब वे अंतिम रूप से मुझे मिलते हैं, और वह अंतिम टी पार कर जाता है, तो सॉफ्टवेयर काम करेगा। कीड़े को हटाने के लिए कभी-कभी यह सही शैली से अधिक लेता है ...

जब मैंने शेल सीखना शुरू किया, तो अधिकांश स्क्रिप्ट और टुट्स ने इन-लाइन सेमीकोलन प्रारूप का उपयोग किया

for i in "$@"; do
    stuff
done

लेकिन क्योंकि मैं अनुभवहीन था, मुझे थोड़ा सा मुश्किल समय था; और दोनों - वाक्यविन्यास शुद्धता की पुष्टि के लिए आवश्यक है। इसलिए मैंने अगली लाइन पर खुद ही इसे करना पसंद किया। मैं अब ऐसा नहीं करूंगा

इसके अलावा, 'जबकि' कमांड एक अच्छी छोटी चाल के लिए एक उत्कृष्ट उम्मीदवार है:

while prep1; prep2; condition; do
    stuff
done

लेकिन जब प्रस्तुत करने का आदेश थोड़ा भारी है, और / या हालत जटिल है, तो यह बेहतर रूप में स्वरूपित है

while
    prep1
    prep2
    condition
do
    stuff
done

और फिर "के रूप में करो" को सकारात्मक रूप से लागू करना है।

आप इससे भी अधिक तीव्र हो सकते हैं:

while
    if con1; then
      cond2
    elif cond3; then
      cond4
    elif cond5; then
      cond6
    else
      cond7
    fi
do
    stuff
done

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

इसलिए! सामान्य रूप से शैल लिपियों की बल्कि बारोक शैलियों को देखते हुए, महत्वपूर्ण प्रतीकों को स्पष्टता और आसान दृश्य पहुंच बढ़ाने के उद्देश्य से कुछ भी हमेशा एक अच्छी बात है।

वह प्रपत्र जहाँ 'do' को कमांड के साथ इनलाइन लिखा जाता है, जब आपके पास थोड़ी कमांड होती है, तो मीठा होता है - मुझे 'do' नेत्रहीन छिपा हुआ नहीं लगता है, और न ही आंतरिक कमांड वास्तव में अस्पष्ट है:

for i in whatever
  do stuff
done

मुझे लगता है कि देखने में काफी सुखद लगता है, और इसके अनुरूप, जबकि, अगर और मामला है:

while condition
  do stuff
end

if condition
  then stuff1
  else stuff2
fi

case $blah in
  a) stuff1;;
  b) stuff2;;
  c) stuff3;;
  *) stuffInfinity;;
esac

स्पष्टता और सामान्य ख़ुशी वह सब है जो आपसे कॉड * पूछता है।

* एडगर एफ। कोडड, रिलेशनल डेटाबेस सिद्धांत के पिता।


1
whileएक ifशर्त के साथ पहले कभी नहीं देखा । ठंडा!
जो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.