শ লুপগুলিতে কেন "কর" পরে নেই?


28

কেন একটি লাইনে লেখার ;পরে doশেল লুপগুলিতে কোনও চরিত্র নেই ?

এখানে আমি যা বলতে চাইছি তা এখানে। যখন একাধিক লাইনে লেখা থাকে, তখন একটি forলুপ দেখতে লাগে:

$ for i in $(jot 2)
> do
>     echo $i
> done

এবং একক লাইনে:

$ for i in $(jot 2); do echo $i; done

সমস্ত ধসে পড়া লাইনগুলি লাইন বাদে; তাদের পরে একটি করে পেয়েছে এবং আপনি যদি এতে অন্তর্ভুক্ত করেন তবে এটি একটি ত্রুটি। আমার চেয়ে অনেক বুদ্ধিমান কেউ সম্ভবত সিদ্ধান্ত নিয়েছিল যে কোনও কারণে এটি করা সঠিক জিনিস, তবে কারণটি কী তা আমি বুঝতে পারি না। আমার কাছে এটি বেমানান বলে মনে হচ্ছে।do;

whileলুপগুলির সাথেও একই ।

$ while something
> do
>     anotherthing
> done
$ while something; do anotherthing; done


2
এটি সামঞ্জস্যপূর্ণ: পরে while/ forহয় কোনও সেমিকোলন নেই ।
দিমিত্রি গ্রিগরিয়েভ

অবিলম্বে মনে যে জিনিসটি আসবে তা হ'ল এটি কেবল প্রয়োজনীয় নয়। অন্য কোথাও, সেমিকোলন বিবৃতি পৃথক করে।
পল ড্রাগার

কারণ এটি অনর্থক হবে। এটি ছাড়া কোনও অস্পষ্টতা নেই।
ব্যবহারকারী 207421

উত্তর:


29

এটি হ'ল কমান্ডের বাক্য গঠন। যৌগিক কমান্ড দেখুন

for name [ [in [words …] ] ; ] do commands; done

বিশেষভাবে নোট করুন: do commands

অধিকাংশ মানুষ করা doএবং commandsসহজ পাঠযোগ্যতা জন্য অনুমতি একটি পৃথক লাইনে কিন্তু এটা প্রয়োজনীয় না হয় তবে আপনি লিখতে পেরেছিলেন:

for i in thing
do something
done

আমি জানি এই প্রশ্নটি বিশেষত শেল সম্পর্কে এবং আমি ব্যাশ ম্যানুয়ালটিতে লিঙ্ক করেছি। এটি শেল ম্যানুয়ালটিতে সেভাবে লেখা হয়নি তবে বাইট ম্যাগাজিনের জন্য স্টিফেন বোর্নের লেখা একটি নিবন্ধে এটি সেভাবেই লেখা হয়েছিল

স্টিফেন বলেছেন:

একটি কমান্ড তালিকা এক বা একাধিক সহজ কমান্ড পৃথক বা একটি newline বা সমাপ্ত একটি ক্রম ;(সেমিকোলন)। তদ্ব্যতীত, সংরক্ষিত মত শব্দ Do এবং সম্পন্ন স্বাভাবিকভাবে একটি newline পূর্বে বা ;কি ... আছে প্রতিটি সময় কমান্ড তালিকা নিম্নলিখিত চালু Do মৃত্যুদন্ড কার্যকর করা হয়।


5
এটি কেন আকর্ষণীয় হবে যে কেন সেমিকোলন থাকতে হবে না , যেমন for i in thing; do; something; done। যথেষ্ট পরিমাণে একটি লাইন বিরতি অনুমোদিত, একটি সেমিকোলন অনুমোদিত নয়।
রেক্সকোগিটান

@ জিডস: হ্যাঁ, ঠিক শেল ব্যাকরণটিও একইভাবে গঠন করা হয়। somethingবিষয় এবং doএটা প্রযোজ্য। ঠিক যেমন ইংরেজী বাক্য কাঠামোয়।
পিটার কর্ডেস

@ জিডস একটি আক্ষরিক (বা সিনট্যাক্সের অন্য কোনও টুকরো) প্রয়োজনীয় কারণ একাধিক কমান্ড শর্তে ( whileসিনট্যাক্সে) যেতে পারে, সুতরাং লুপ বডি কমান্ডগুলি থেকে শর্ত কমান্ডকে পৃথক করার জন্য আপনার কিছু প্রয়োজন। ব্যবহার doতাদেরকে পৃথক সম্ভবত কি কেবল সবচেয়ে মানানসই লাগে হয়।
জোল

@rexkogitans আসলে, আমি কখনই বুঝতে পারি নি যে এটি একটি সিনট্যাক্স ত্রুটি ছিল। এই শিরোনাম প্রশ্নটিও এটি খুব মানানসই। এটি সম্ভবত খালি শরীরের অনুমতি না দেওয়ার সাথে সম্পর্কিত। যদিও নিউলাইনগুলি দিয়ে খালি দেহ তৈরি করার সময় আপনি কিছুটা আলাদা সিনট্যাক্স ত্রুটি পেয়েছেন, এবং আপনার উদাহরণের খালি শরীর নেই।
জোল

@rexkogitans সেমিকোলন এখানে লুপ সিনট্যাক্সের একটি অংশ এবং কমান্ড-তালিকা টার্মিনেটর হিসাবে এটির অন্যান্য ভূমিকা থেকে পৃথক। নিউলাইনটি আলাদা কারণ কারণ এটি অন্যথায় প্রয়োজন বা প্রত্যাশিত না হলে এটি সাধারণ সাদা স্থানের মতো বিবেচনা করা হয়। শেল ব্যাকরণ অগোছালো।
চিপনার

12

আমি এই সিনট্যাক্সের মূল কারণটি জানি না, তবে আসুন whileলুপগুলি শর্ত বিভাগে একাধিক কমান্ড নিতে পারে তা বিবেচনা করুন eg

while a=$(somecmd);
      [ -n "$a" ];
do
    echo "$a"
done

এখানে, doকীওয়ার্ডটি শর্ত বিভাগ এবং লুপের প্রধান অংশটি পৃথক করার জন্য প্রয়োজনীয়। doএকটি শব্দ ভালো হয় while, ifএবং then(এবং done), এবং এটি অন্যদের সঙ্গে সঙ্গতিপূর্ণ হতে হবে যে তা পরে একটি সেমিকোলন বা সম্পর্কে newline দরকার নেই, তবে কমান্ড সামনে অবিলম্বে প্রদর্শিত হবে বলে মনে হয়।

বিকল্পটি (সাধারণকরণে ifএবং while) কিছুটা কুৎসিত দেখায়, আমাদের উদাহরণ লিখতে হবে

if; [ -n "$a" ]; then
    some command here
fi

forলুপগুলির বাক্য গঠনটি ঠিক একই রকম।


11

শেল সিনট্যাক্স উপসর্গ ভিত্তিক। এটিতে বিশেষ কীওয়ার্ড দ্বারা کلاস চালু করা হয়েছে। নির্দিষ্ট কিছু ধারা একসাথে যেতে হবে।

একটি whileলুপ এক বা একাধিক পরীক্ষার কমান্ড তৈরি করা হয়:

test ; test ; test ; ...

এবং এক বা একাধিক বডি কমান্ড দ্বারা:

body ; body ; body ; ...

শেলকে কিছু বলতে হবে যে কিছুক্ষণের জন্য লুপ শুরু হয়। এটাই whileশব্দের উদ্দেশ্য :

while test ; test ; test ; ...

তবে তারপরে বিষয়গুলি দ্বিধাবিভক্ত। দেহের সূচনা কোন আদেশ? কিছু এটি নির্দেশ করতে হবে এবং এটি doউপসর্গটি করে:

do body ; body ; body ; ...

এবং, অবশেষে, কিছুতে ইঙ্গিত করতে হবে যে শেষের শরীরটি দেখা গেছে; একটি বিশেষ কীওয়ার্ড doneএটি করে।

এই শেল কীওয়ার্ডগুলির জন্য একই লাইনেও সেমিকোলন বিচ্ছেদ প্রয়োজন হয় না। উদাহরণস্বরূপ, যদি আপনি বেশ কয়েকটি নেস্টেড লুপগুলি বন্ধ করেন তবে আপনার কাছে কেবল এটি থাকতে পারে done done done ...

বরং সেমিকোলন ... test ; body ... যদি একই লাইনে থাকে তবে এর মধ্যে থাকে। সেমিকোলনটি একটি টার্মিনেটর হিসাবে বোঝা যায়: এটি এর সাথে সম্পর্কিত test। সুতরাং, যদি doতাদের মধ্যে কোনও কীওয়ার্ড প্রবেশ করানো হয় তবে এটি সেমিকোলন এবং এর মধ্যে যেতে হবে body। এটি যদি সেমিকোলনের অন্য দিকে থাকে তবে এটি testকমান্ডের সিনট্যাক্সের ভিতরে কমান্ডের মধ্যে স্থাপন না করে ভুলভাবে এম্বেড করা হত ।

শেল সিনট্যাক্সটি মূলত স্টিফেন বোর্ন ডিজাইন করেছিলেন এবং আলগোল দ্বারা অনুপ্রাণিত হয়েছেন । বোর্ন আলগলকে এত পছন্দ করতেন যে তিনি সিটিকে আলগোলের মতো দেখতে শেল উত্স কোডে প্রচুর সি ম্যাক্রো ব্যবহার করেছিলেন। আপনি সংস্করণ 7 ইউনিক্স থেকে 1979-তারিখের শেল উত্সগুলি ব্রাউজ করতে পারেন । ম্যাক্রোগুলি ভিতরে রয়েছে mac.hএবং এগুলি পুরো জায়গা জুড়ে ব্যবহৃত হয়। জন্য উদাহরণস্বরূপ ifবিবৃতিগুলির মতো দেখা যায় IF... ELSE... ELIF... FI


উত্স কোডটি চিত্তাকর্ষক।
কিথপজল্লি

হ্যাঁ, এটি সিপিসির একটি ট্যুর ডি ফোর্স।
চোরমোহেন্ট

7

আমি তর্ক করব যে doএখানে বিশেষ বিশেষ নয়। আপনি একটি ত্রুটি পান কারণ ;একটি আদেশ তালিকা শুরু করতে পারে না। যদি এটি হয়, প্রথম কমান্ডটি খালি হবে, এবং ব্যাকরণ খালি কমান্ডগুলিকে অনুমতি দেয় না (কোনও আদেশ ছাড়াই পরিবর্তনশীল অ্যাসাইনমেন্ট বা পুনঃনির্দেশ, হ্যাঁ, তবে একেবারেই কিছুই নয়, না)। আদেশের তালিকা প্রত্যাশিত যেখানেই এটি যে কোনও স্থানেই এটি সত্য:

$ while true; do ; echo foo; done
dash: 1: Syntax error: ";" unexpected
$ while ; true; do; echo; done
dash: 1: Syntax error: ";" unexpected
$ { ; echo foo; }
dash: 1: Syntax error: ";" unexpected
$ if ; true; then echo foo; fi
dash: 1: Syntax error: ";" unexpected

এমন কি:

$ ; ;
dash: 1: Syntax error: ";" unexpected

এই সমস্ত জায়গায়, একটি কমান্ড তালিকা প্রত্যাশিত এবং তাই একটি নেতৃত্ব ;অপ্রত্যাশিত।


হ্যাঁ - আমি যেভাবে নির্বিচারে 'ডু' করার পরে 'do n' যুক্ত করেছি তা আমাকে মনে করে যে 'কর' এককভাবে টোকেন ছিল এবং এটি এমন কোনও কিছু নয় যা পরবর্তী ব্লকটিতে কাজ করে।
কিথপজল্লি

কীভাবে এমন একটি পলাতক নিউলাইনকে (যা অন্যথায় শেল সিনট্যাক্সে অর্ধিকরণের মতো আচরণ করে ), (এবং ইত্যাদি) এর পরেও কীভাবে অনুমোদিত ? doif
হেনিং মাখোলম

@ হেনিং কোনও কমান্ড তালিকার আগে (এবং পরে) যে কোনও সংখ্যক নতুন লাইনের অনুমতি রয়েছে। নিউলাইনস এবং সেমিকোলনগুলি অন্যান্য দিকগুলিতেও আলাদা আচরণ করে। উদাহরণস্বরূপ, উপন্যাস সম্প্রসারণ করা হয় যখন সম্পূর্ণ ইনপুটটির সম্পূর্ণ লাইনটি পড়ে (যেমন, পরবর্তী নতুনলাইন পর্যন্ত), এবং প্রতি আদেশ অনুসারে নয়।
3:25

3

বাক্য গঠনটি হ'ল:

for i in [whitespace separated list of values]
do [newline separated list of commands]
done

কমান্ড তালিকায় অথবা "কর" বা "সম্পন্ন" এর আগে যে কোনও নতুন লাইনের পরিবর্তে ";" দ্বারা প্রতিস্থাপন করা যেতে পারে।

একটি newline (কিন্তু একটি ";") করা হয় অনুমতি "do" পরে এবং আগে "এ", শুধু কিছু সুন্দর বানাতে, কিন্তু এটা জানার জন্য না প্রয়োজন, একটি newline আছে।


3

if এর কীওয়ার্ডগুলির সাথে সমান: কমান্ডগুলি ছোট হয়ে গেলে এটি বেশ পঠনযোগ্য:

if   test_commands
then true_commands
else false_commands
fi

একবার আমি বুঝতে পেরেছিলাম যে আমি সমস্ত সার্থক \nহওয়ার পরে একটি সালিশী রাখছি do(যতক্ষণ আপনি অন্য কমান্ড এবং আর্গসের মধ্যে একটি স্বেচ্ছাসেবী স্থাপন করতে সক্ষম না হওয়ার কথা ভাবেন না \n)।
কিথপজল্লি 14

ওয়েল, do, then, elseনেই args - যদি তারা ছিল, আপনি তাদের পূর্বে একটি সেমিকোলন ব্যবহার করার অনুমতি দেওয়া হবে না। এগুলি শেল কীওয়ার্ডগুলি (দেখুন type if then elif else fi)
গ্লেন জ্যাকম্যান

আমি অনুমান করি যে আমি আমার উত্তরে থাকতে চেয়েছি তেমন পরিষ্কার ছিলাম না।
কিথপজল্লি

আমার বক্তব্যটি ছিল যে "কর" কোনও "অন্যান্য আদেশ" এর মতো নয়। সুতরাং এটি বিভিন্ন বিধি পালন করে।
গ্লেন জ্যাকম্যান

3

সংক্ষিপ্ত উত্তর, কারণ এটি POSIX শেল ব্যাকরণ দ্বারা নির্দিষ্ট করা হয়েছে । মধ্যে যেকোনো কিছু doএবং done, বিবৃতি একদল বিবেচিত যখন হয় ;অনুক্রমিক বিভাজক হল:

for_clause       : For name                                      do_group
                 | For name                       sequential_sep do_group
                 | For name linebreak in          sequential_sep do_group
                 | For name linebreak in wordlist sequential_sep do_group

do_group         : Do compound_list Done 

sequential_sep   : ';' linebreak
                 | newline_list

তদ্ব্যতীত, ;প্রয়োজনীয় হলে মানটি স্পষ্টভাবে উল্লেখ করে এবং এর sequential_sepপরে অন্তর্ভুক্ত করবে Do


1
@ ড্র্রুবেন আপনারা প্রথমটি বোঝাতে চান? এটি অবস্থানগত পরামিতিগুলির মাধ্যমে পুনরাবৃত্তি করছে। সুতরাং আপনার কাছে ./myscript.sh abc এর মতো স্ক্রিপ্ট থাকলে, যেখানে abc আর্গুমেন্ট, i এর জন্য লুপ; ইকো "$ i"; আবদুর মাধ্যমে লুপ হবে, যদিও আমি এখনও মনে করি এটির কাজ করার জন্য এটির জন্য সেমিকোলন প্রয়োজন হবে
সের্গি কলডিয়াজহনি

ঠিক আছে, তাই আমার সন্দেহগুলিও সাফ হয়ে গেছে
সের্গেই কোলডিয়াজনি

1

কারণ কর হ'ল একটি কীওয়ার্ড এবং যা অনুসরণ করে তা মূলত পরামিতি। ব্যাশ ইন্টারপ্রেটার আরও জানায় যে। এটি কীভাবে 'নেই' এর সমান; কমান্ডের জন্য i অনুসরণ করে। আই ইন-এর পরে আপনি একটি নতুন লাইন যুক্ত করতে পারেন এবং বাকীটি একটি নতুন লাইনে টাইপ করতে পারেন এবং এটি দুর্দান্ত কাজ করবে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.