কেন ksh এ "[[" এবং "-e xxx" এর মধ্যে একটি ফাঁকা প্রয়োজন?


9

উদাহরণস্বরূপ, নিম্নলিখিত কমান্ডটি কাজ করে না:

if [[-e xyz]]; then echo File exists;fi

ksh নিম্নলিখিত ত্রুটি দেয়

[[-e: command not found

এর কারণ কি "[[-" দ্বিধাগ্রস্ত?


2
[[একটি কীওয়ার্ড - সম্ভবত শেলের পার্স গাছটি
শ্বেতস্পেসের

এটির আরেকটি উপায় সম্ভবত সম্ভবত আপনি একটি ফাংশন লিখতে পারেন [[-, শেল কীভাবে "ফাংশনটি [[" - "এর পরিবর্তে [[" এ ই পতাকা করতে পার্স করতে শিখবে।
pbhj

উত্তর:


15

সরলতম ব্যাখ্যা হবে, ম্যানুয়াল মনে হচ্ছে কারণ হিসেবে [[ expression ]]তাই মধ্যে স্থান হতে হয়েছে [[এবং expressionএবং বন্ধ ]]। তবে অবশ্যই আমরা এটিকে আরও গভীরতার সাথে দেখার চেষ্টা করতে পারি। শাঁসগুলির কিছুটা জটিল ব্যাকরণ রয়েছে এবং "শব্দ বিভাজন" ধারণার উপর প্রচুর নির্ভর করে। বিশেষত, ksh (1) ম্যানুয়ালটিতে বলা হয়েছে:

শেলটি তার ইনপুটটিকে শব্দগুলিতে ভেঙে পার্স করা শুরু করে। শব্দগুলি, যা অক্ষরের ক্রম, অব্যক্ত সাদা-স্থানের অক্ষর (স্পেস, ট্যাব এবং নিউলাইন) বা মেটা-অক্ষর (<,>, |,;, &, (এবং)) দ্বারা সীমিত হয়। সীমিত শব্দ ছাড়াও, ফাঁকা স্থান এবং ট্যাবগুলি অগ্রাহ্য করা হয়, যখন নিউলাইনগুলি সাধারণত কমান্ডগুলি সীমিত করে।

যেমন ম্যানুয়ালটিতে বলা হয়েছে, অক্ষরের ক্রমকে [[-eশেল শব্দ হিসাবে বিবেচনা করা হয়। kshবিল্ট-ইন এবং বিশেষ অপারেটরগুলির (যেমন forবা while) এর তালিকায় এই জাতীয় কমান্ড সন্ধান করবে , এবং তারপরে একটি বাহ্যিক কমান্ড সন্ধান করবে - এবং ভয়েলি - কিছুই পাওয়া যায় নি, সুতরাং কমান্ড সম্পর্কে একটি ত্রুটি বার্তা পাওয়া যায় নি।

এই ক্ষেত্রে [[বিশেষ মেটা-অক্ষর পারেন না। যদি সেগুলি হয়, -eঅংশটি [[-eশেল শব্দ হিসাবে বিবেচিত হবে, [[নিজের পক্ষে যুক্তি নয়। তবে [[যৌগিক কমান্ড হিসাবে বর্ণনা করা হয়েছে, এবং ম্যানুয়ালটিতে নিম্নলিখিতটি বলা হয়েছে:

যৌগিক কমান্ডগুলি নিম্নলিখিত সংরক্ষিত শব্দগুলি ব্যবহার করে তৈরি করা হয় - এই শব্দগুলি কেবল তখনই স্বীকৃত হয় যদি সেগুলি উদ্ধৃত হয় না এবং যদি সেগুলি কোনও কমান্ডের প্রথম শব্দ হিসাবে ব্যবহৃত হয় (যেমন, তারা প্যারামিটার অ্যাসাইনমেন্ট বা পুনঃনির্দেশ দ্বারা অগ্রসর হতে পারে না):

সুতরাং [[একটি যৌগিক কমান্ড হিসাবে স্বীকৃতি পাওয়ার জন্য , এটি একটি কমান্ড বা কমান্ড তালিকার প্রথম শব্দ হতে হবে, যা "শব্দের" পূর্ববর্তী সংজ্ঞা দ্বারা বোঝায় যে এটি স্পেস, ট্যাব বা অন্য থেকে নতুন লাইনের দ্বারা পৃথক করতে হবে শব্দ / আর্গুমেন্ট।


আপনি মন্তব্যে জিজ্ঞাসা করেছেন : "" [["ধাঁচটি খুঁজে পাওয়ার সাথে সাথে পার্সারটি কেন থামতে পারে না এবং এটি শর্তসাপেক্ষ আদেশের শুরু হিসাবে বিবেচনা করে?" সংক্ষিপ্ত উত্তর সম্ভবত কারণ 1) [সিনট্যাক্সের প্রভাব যেহেতু এটি মূলত একটি বাহ্যিক আদেশ ছিল এবং পসিক্সের জন্য মানক সম্মতিটি আজও বাহ্যিক কমান্ড হিসাবে বিদ্যমান এবং 2) কারণ শেল পার্সারটি নির্মিত হয়েছে। শেল পার্সার অন্যান্য অ-স্থান নির্ধারিত বিশেষ অক্ষরগুলি সনাক্ত করতে পারে: echo $((2+2))এবং (echo foobar)পুরোপুরি সূক্ষ্মভাবে কাজ করে। সম্ভবত ভবিষ্যতে যখন kshউন্নয়ন আবার শুরু হবে বা সেখানে কাঁটাচামচ বা ক্লোন উপস্থিত হবে (যেমন mkshবা pdksh) কেউ স্থান কম কম সিনট্যাক্স প্রয়োগ করবে [[-e

আরো দেখুন:


3
আমি মনে করি ksh ম্যানুয়াল উদ্ধৃতিটি সত্যই ঘটনাস্থলে রয়েছে। এটি অন্য যে কোনও প্রোগ্রামিং ভাষার সাথে সমান: সি charতে একটি কীওয়ার্ড তবে আপনি এখনও লিখতে পারবেন না charsomeletter = 'A';এবং পার্সারটি দেখার পরে থামার আশা করতে পারেন char
পিটার - মনিকা পুনরায়

আমি মনে করি আপনার "চর" উদাহরণ এবং "[[" চিহ্নের প্রশ্নের মধ্যে প্রধান পার্থক্যটি হ'ল, একটি বর্ণানুক্রমিক সনাক্তকারী, সাধারণভাবে, অন্যদের থেকে পৃথক হওয়ার জন্য স্পেস ডিলিমিটারের প্রয়োজন হয়; অন্যদিকে টোকেন হিসাবে বিশেষ চিহ্নগুলির জন্য স্পেস ডিলিটারগুলির প্রয়োজন নেই।
ACBap

যথাযথভাবে। আমি নিশ্চিত না যে সি এর সাথে তুলনা করা সহায়ক। সিতে কেউ বলতে পারেন i--<=++j, এবং সংকলকটিকে পার্স করার ক্ষেত্রে কোনও সমস্যা নেই i -- <= ++ j
স্কট

@ স্কট আমি সি সি তুলনা সহায়ক বলে মনে করি (এবং এটি গৌণিক ধরণের যে সি সনাক্তকারীরা কেবলমাত্র আলফানিউমারিকস এবং মঞ্জুরি দেয় _)। Ksh এর অপারেটর( হিসাবে রয়েছে এবং পার্স করে । এটা তোলে করেছে , , , এবং অন্যান্য কীওয়ার্ড এবং , এবং প্রতিটি এক টোকেন হয় - কিভাবে মত এক সি টোকেন হয়। বিপরীতে, কেএস- তে একটি অচিহ্নিত দুটি টোকেন - যেমন সি তে দুটি টোকেন কীভাবে বোঝা যায় এটি অপারেটর হিসাবে ধারণার অর্থ যা বর্ন-স্টাইলের শেলগুলির (কেএসএসের মতো) এবং সি এর মধ্যেও পার্থক্য করে তবে পিটার এ স্নাইডার একটি বিষয় উল্লেখ করেছেন আসল লেক্সিকাল মিল। (echo hello)( echo hello )if{[[ifx{x[[xcharsomeletter(xi--
এলিয়াহ কাগন

2

গুরুত্বপূর্ণ বিষয়টি যা লক্ষ্য করা যায় তা [হ'ল একটি কমান্ড [[এবং বাশ এবং ksh এ থাকা শেল কীওয়ার্ডটি ভিত্তিক [

[[একইভাবে ব্যবহার করা হয় [কখনও কখনও আপনি এমনকি প্রতিস্থাপন করতে পারেন [ ]সঙ্গে [[ ]]আচরণের কোন পরিবর্তনের সঙ্গে। সঙ্গে [, কোনো কমান্ডের অনুরূপ একটি স্থান কমান্ড ও এর আর্গুমেন্ট মধ্যে বাধ্যতামূলক। একই প্রযোজ্য [[

আমরা শুধুমাত্র ছিল /usr/bin/[। এখন বেশিরভাগ শেলগুলি [দক্ষতার জন্য তৈরি করেছে - তবে বাক্য গঠন একই is সরবরাহকারী শেলগুলিতে এটি আরও বহুমুখী বিকল্প [[হিসাবে কাজ করে ।[

এখানে [বাশ-এর বিবরণ দেওয়া হল :

$ help [
[: [ arg... ]
    Evaluate conditional expression.

    This is a synonym for the "test" builtin, but the last argument must
    be a literal `]', to match the opening `['.

সুতরাং [সমান test( ]একেবারে শেষের দিকে কোন যুক্তির প্রত্যাশা বাদ দিয়ে )। help testএটি আরও বিস্তারিত জানাতে হবে। আপনি এটি তুলনা করতে পারেন help [[

বহিরাগত কমান্ডের জন্য একটি ম্যান পৃষ্ঠা রয়েছে [( man \[)।

এর ব্যাপারে

if [[-e
  • না হুকুম [নেই [[, সেখানেও নেই। পুরো শব্দটি [[-eহ'ল।
  • if [[-eএটা কি সত্যি / মিথ্যা একটি পরীক্ষামূলক করে তোলে। সুতরাং একটি আদেশ [[-eআছে কি?

এর কারণ কি "[[-" দ্বিধাগ্রস্ত?

হ্যাঁ. অথবা না. [[-eএটি হ'ল: শেল যে কিছুই বুঝতে পারে তাই এটি এটি নিজস্ব কমান্ড বলে ধরে নেয়। ;-)


"% সহায়তা [[" বলে যে "[[" একটি শর্তাধীন আদেশ) command "[[" প্যাটার্নটি খুঁজে পাওয়ার সাথে সাথে পার্সারটি কেন থামতে পারে না এবং এটি শর্তসাপেক্ষ আদেশ হিসাবে শুরু হিসাবে বিবেচনা করে?
ACBap

@ মাইলতি [[-eহ'ল একটি সম্ভাব্য বৈধ (যদি অদ্ভুত- সন্ধানী ) কমান্ডের নাম।
গর্ডন ডেভিসন

2

স্থানটি একটি বিস্ময়কর এবং প্রয়োজনীয়। যেমন আপনি দেখতে পাচ্ছেন shellcheck:

$ shellcheck gmail-browse-msgs-algorithm.sh

In gmail-browse-msgs-algorithm.sh line 847:
        [[$Today != "${DaysArr[ i + DAY_DELETED_ON_NDX ]}" ]] && continue
          ^-- SC1035: You need a space after the [[ and before the ]].

(Ksh এবং bash উভয় সমর্থন করে [[এবং স্থান ব্যতীত কাজ করে না She শেলচেক সেই বগি লাইনযুক্ত অনুরূপ ksh এবং ব্যাশ স্ক্রিপ্টগুলির সাথে ঠিক সেই আউটপুট দেয়))

কেন ডিলিমিনেটরগুলির প্রয়োজন তা টোকেন এবং অভিধানের সাথে করা উচিত ।


দয়া করে নোট করুন, ওপি kshপ্রশ্নের শেল সম্পর্কে জিজ্ঞাসা করেছিল। ব্যাশ ধার [[থেকে অপারেটর kshএবং এই প্রশ্ন তাদের আচরণ অভিন্ন মধ্যে, কিন্তু তার মাঝে কিছু উল্লেখযোগ্য পার্থক্য আমি অনুমানের সতর্ক হবে kshএবং bashআচরণ এবং অভ্যন্তরীণ। এটি কেবল কারণ শেলচেক ব্যাশ স্ক্রিপ্টে কাজ করে, এটি সম্ভবত ksh স্ক্রিপ্টগুলির জন্য উপযুক্ত সরঞ্জাম নাও হতে পারে। বিভিন্ন শাঁসের কাছে যাওয়ার সময় কেবল কিছু মনে রাখা উচিত
সের্গি কলডিয়াজহনি

@ সার্জিইকলোডিএজনি আমি [[অন্তর্নির্মিত নিয়মগুলি হাইলাইট করতে শেলচেক ব্যবহার করে সুবিধাবাদী হয়ে উঠছিলাম । আমি কোন ভাবেই inferring যে ছিল kshএকটি শেল ছিল shellcheckত্রুটি খুঁজে পাইনি। আমি আশা করি অন্যদের প্রশংসা kshএবং bashদুটি ভিন্ন দোভাষী হয়। যে উল্লেখ করার জন্য আপনাকে ধন্যবাদ। এছাড়াও লক্ষণীয় মূল্য হ'ল একটি বাহ্যিক কমান্ডের [[সাথে অন্তর্নির্মিত বাশ [
WinEunuuchs2Unix

প্রকৃতপক্ষে [একটি অন্তর্নির্মিত বাশও হ'ল :) manpages.ubuntu.com/manpages/bionic/man7/bash-builins.7.html তবে আপনি খুব বেশি দূরে নন - [বা testএকটি বাহ্যিক আদেশ হতে হবে। আসল বোর্নের শেলগুলির দিনগুলিতে[ আসলে একটি বাহ্যিক কমান্ড ছিল এবং আজকাল বিদ্যমান /usr/bin/[কারণ পসিক্সের এটি একটি বাহ্যিক কমান্ড পাবস প্রয়োজন op বিল্ট-ইন করা pubs.opengroup.org/onlinepubs/009695399/idx/sbi.html Builtin [দক্ষতা জন্য
Sergiy Kolodyazhnyy

2
শেলচেক জানে ksh; একটি হ্যাশবাং বা ব্যবহার করুন -s ksh। বিটিডাব্লু, কেএসএস এবং ব্যাশের [["বিল্ট ইন" রয়েছে তবে এটি একটি কীওয়ার্ড নয় [, এর বিপরীতে যা শেল বিল্টিন । (ksh :; whence -v [ [[bash type [ [[:) বিল্টিনস এবং বাহ্যিক আদেশগুলি সিনট্যাক্টিকভাবে এক রকম। একটি উপায় এর [[থেকে পৃথক [হ'ল [[তার যুক্তিগুলিতে কিছু বিস্তৃতিকে দমন করে, যা এটি কোনও বিল্টিন হিসাবে {পারেনি - যতটা গ্রুপিং করতে পারত না এটি কোনও বিল্টিন ছিল। এই কারণেই {x(বা [[x) এক টোকেনকে বিজোড় মনে হয়। আমার মনে হয় এটা ঠিক বলতে builtins এবং কীওয়ার্ড হয় আভিধানিক কিন্তু চিহ্নগুলি সিন্টেক্সের অনুরূপ। @ সার্জিইক্লোডিয়াজনি
এলিয়াহ

1
@ এলিয়াকাগান প্রকৃতপক্ষে, আমি ইউএসএল-তে একটি প্রশ্ন পোস্ট করেছি যাতে এই পরিস্থিতি সম্পর্কে পোসিক্স কী মনে করেন সে সম্পর্কে একটি সুনির্দিষ্ট উত্তর পেতে ইউনিক্স.স্ট্যাকেক্সেক্সঞ্জ / প্রশ্ন / ৫২27474৪/২ শেল ভাষা যথেষ্ট জটিল তাই আশা করি কেউ আরও আনুষ্ঠানিক শর্তে এটি ব্যাখ্যা করতে পারবেন
সের্গেই কোলোডিয়াজনি

1

[[বাহ্যিক আদেশ হতে পারে! এটি হ'ল এটি একটি প্রোগ্রাম হতে পারে এবং সরাসরি আপনার শেল দ্বারা সমর্থিত কোনও সিনট্যাক্স নয়। কোনও স্থান-কম সিনট্যাক্সের পক্ষে সমর্থন করা সম্ভব হবে kshতবে এটি বাহ্যিক সিস্টেমগুলিতে ব্যর্থ হবে [[সুতরাং সামঞ্জস্যতার কারণে প্রয়োজনীয় স্থান রাখা ভাল।

ব্যজিবক্স[[ উদাহরণস্বরূপ একটি বাহ্যিক কমান্ড হিসাবে সরবরাহ করছে


0

যেহেতু [[-eশেল সম্প্রসারণে অংশ নিতে পারে (এটি ব্যবহার করা যেতে পারে

echo [[-e]*

সমস্ত ফাইলকে একটি বর্ণের সাথে শুরু করে [এবং eঅন্তর্ভুক্তের সাথে তালিকাভুক্ত করার জন্য ) এটি সম্পূর্ণ গণ্ডগোল হবে যদি [এবং যদি ]বিশেষ চরিত্রগুলি সাধারণ শ্বেতক্ষেত্র-নিয়ন্ত্রিত শব্দ বিভাজনে অংশ না নেয়।

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