ব্রেস সম্প্রসারণ এবং কমান্ড গ্রুপিংয়ের মধ্যে বাশ কীভাবে পার্থক্য করতে পারে?


47

আমি লক্ষ্য করেছি যে {ব্রেস সম্প্রসারণে ব্যবহার করা যেতে পারে:

echo {1..8}

বা কমান্ড গ্রুপিংয়ে:

{ls;echo hi}

বাশ কীভাবে পার্থক্য জানতে পারে?


1
দুর্দান্ত প্রশ্ন, +1। দেখে মনে হচ্ছে এটি {কমান্ডের তালিকা হিসাবে ব্যাখ্যা করা হতে পারে যদি এটি কোনও কমান্ডের শুরুতে প্রদর্শিত হয় এবং অন্যথায় ব্রেস প্রসারণ হিসাবে উপস্থিত হয় তবে আমি নিশ্চিত নই।
সেলেদা

16
{ls;echo hi}আইনি নয় bash। প্রারম্ভিক বন্ধনীগুলির পরে আপনার একটি স্থান এবং বন্ধের আগে একটি সেমিকোলন প্রয়োজন You
পিএসকোকিক

উত্তর:


38

একটি সরলীকৃত কারণ একটি অক্ষর অস্তিত্ব হল: space

ধনুর্বন্ধনী বিস্তৃতি স্থান (প্রক্রিয়াবিহীন) প্রসেস করে না।

একটি {...}তালিকার প্রয়োজন (অ-উদ্ধৃত) ফাঁকা স্থান।

আরও বিশদ উত্তর হ'ল শেল কীভাবে একটি কমান্ড লাইনকে পার্স করে


কমান্ড লাইনটি পার্স (বোঝার) প্রথম পদক্ষেপ হ'ল এটিকে কিছু অংশে বিভক্ত করা।
এই অংশগুলি (সাধারণত শব্দ বা টোকেন নামে পরিচিত) লিঙ্কটি থেকে প্রতিটি মেটা-চরিত্রের একটি কমান্ড লাইন ভাগ করে ফলাফল :

  1. কমান্ডটি টোকেনগুলিতে বিভক্ত করে যা মেটা-অক্ষরগুলির নির্দিষ্ট সেট দ্বারা পৃথক করা হয়: স্পেস, ট্যাব, নিউলাইন,;, (,), <,>, |, এবং &। টোকেনের প্রকারের মধ্যে শব্দ, কীওয়ার্ড, আই / ও রিডাইরেক্টর এবং সেমিকোলন রয়েছে।

মেটা-অক্ষর: spacetabenter;,<>|এবং &

বিভক্ত হওয়ার পরে শব্দগুলি একটি ধরণের হতে পারে (শেল দ্বারা বোঝা যায়):

  • কমান্ড প্রাক অ্যাসিমেটমেন্টস: LC=ALL ...
  • হুকুম LC=ALL echo
  • যুক্তি LC=ALL echo "hello"
  • ফেরৎ LC=ALL echo "hello" >&2

বন্ধনী সম্প্রসারণ

কেবলমাত্র যদি "ব্রেস স্ট্রিং" (স্পেস বা মেটা-অক্ষর ব্যতীত) কোনও একক শব্দ হয় (উপরে বর্ণিত হিসাবে) এবং উদ্ধৃত না করা হয় তবে এটি "ব্রেস প্রসারণ" এর প্রার্থী। অভ্যন্তরীণ কাঠামো পরে আরও চেক করা হয়।

সুতরাং, এটি: হয় হিসাবে বা (বাশ, zsh পৃথক পৃথক) {ls,-l}হয়ে "ব্রেস সম্প্রসারণ" ls -lহিসাবে যোগ্যতা অর্জন করে।first wordargument

$ {ls,-l}            ### executes `ls -l`
$ echo {ls,-l}       ### prints `ls -l`

কিন্তু এই এগুলি করবেন না: {ls ,-l}। বাশ বিভক্ত হবে spaceএবং দুটি শব্দ হিসাবে লাইনটি পার্স করবে: {lsএবং ,-l}যা একটি ট্রিগার করবে command not found(যুক্তিটি ,-l}হারিয়ে গেছে):

 $ {ls ,-l}
 bash: {ls: command not found

আপনার লাইন: দুটি মেটা-চরিত্র এবং {ls;echo hi}এর কারণে "ব্রেস এক্সপেনশন" হয়ে উঠবে না ।;space

এটা এই তিনটি অংশ ভেঙে হবে: {lsনতুন কমান্ড প্রয়োগ করুন: echo hi}। বুঝতে পারেন যে ;একটি নতুন কমান্ড শুরু হওয়ার সূত্রপাত করে। কমান্ডটি {lsপাওয়া যাবে না এবং পরবর্তী কমান্ডটি মুদ্রণ করবে hi}:

$ {ls;echo hi}
bash: {ls: command not found
hi}

যদি এটি অন্য কোনও কমান্ডের পরে স্থাপন করা হয় তবে এটি এর পরেও একটি নতুন কমান্ড শুরু করবে ;:

$ echo {ls;echo hi}
{ls
hi}

তালিকা

"যৌগ কমান্ড" এক (আমার শব্দ) একটি "বন্ধনী তালিকা" is: { list; }
আপনি দেখতে পাচ্ছেন, এটি স্পেস এবং একটি ক্লোজিংয়ের সাথে সংজ্ঞায়িত ;
স্পেস এবং ;প্রয়োজনীয় কারণ উভয় {এবং }"সংরক্ষিত শব্দ "।

এবং তাই, শব্দ হিসাবে স্বীকৃতি পেতে, অবশ্যই মেটা-অক্ষর দ্বারা বেষ্টিত হওয়া উচিত (প্রায় সর্বদা space:)।

সংযুক্ত পৃষ্ঠার 2 পয়েন্টে বর্ণিত হিসাবে

  1. প্রতিটি কমান্ডের প্রথম টোকেন পরীক্ষা করে দেখুন এটি ...., {, বা (, তবে কমান্ডটি আসলে একটি যৌগিক কমান্ড)।

আপনার উদাহরণ: {ls;echo hi}একটি তালিকা নয়।

এটির পরে একটি ক্লোজিং ;এবং একটি স্থান প্রয়োজন (কমপক্ষে) {। শেষটি }ক্লোজিং দ্বারা সংজ্ঞায়িত করা হয় ;

এটি একটি তালিকা { ls;echo hi; }। এবং { ls;echo hi;}এটিও (কম ব্যবহৃত হয় তবে বৈধ) (সহায়তার জন্য @ চোরোবা ধন্যবাদ)।

$ { ls;echo hi; }
A-list-of-files
hi

কিন্তু একটি কমান্ডের পক্ষে আর্গুমেন্ট হিসাবে (শেল পার্থক্যটি জানে), এটি একটি ত্রুটি ঘটায়:

$ echo { ls;echo hi; }
bash: syntax error near unexpected token `}'

তবে শেলটি যেটি পার্স করছে তা আপনি কীভাবে সতর্ক হন:

$ echo { ls;echo hi;
{ ls
hi

2
এটি সত্যিই সর্বোত্তম উত্তর, কারণ আপনি আমাদের দেন যে বাশ পার্সার কীভাবে কাজ করে! এবং একটি বিস্তারিত ব্যাখ্যা সহ!
lovespring

2
আপনার মাঝে ;এবং এর মধ্যে জায়গার দরকার নেই }{ ls;}সেমিকোলন ইতিমধ্যে একটি মেটা-চরিত্র হিসাবে কাজ করে।
চোরোবা

1
@ লভ্যাসপ্রিং ধন্যবাদ, হ্যাঁ আমি এটি লেখার জন্য কিছুটা সময় ব্যয় করেছি। আমি এটি দরকারী যে জেনে খুশি। আবারও, ধন্যবাদ।

চমৎকার নিবন্ধ, উল্লেখের জন্য অনেক ধন্যবাদ
এডওয়ার্ড টরভাল্ডস

16

ব্লকটি {একটি শেল কীওয়ার্ড, সুতরাং এটি অবশ্যই পরবর্তী শব্দটি স্পেস দ্বারা পৃথক করতে হবে, যখন ব্রেস প্রসারিত করার সময়, কোনও স্থান থাকা উচিত নয় (যদি আপনাকে কোনও স্থান প্রসারিত করার প্রয়োজন হয় তবে আপনাকে এড়াতে হবে echo {\ ,a}{b,c}:)।

কমান্ডের শুরুতে আপনি বন্ধনী সম্প্রসারণ ব্যবহার করতে পারেন:

{ls,.}  # expands to "ls ."

আপনি কোনও ব্লকে প্রসারিত করতে এটি ব্যবহার করতে পারবেন না, যদিও সম্প্রসারণের আগে গ্রুপিং কমান্ডগুলির বিশ্লেষণ ঘটে:

echo {'{ ls','.;}'}  # { ls .;}
{'{ ls','.;}'}       # bash: { ls: No such file or directory

5

এটি কমান্ড লাইনের বাক্য গঠন পরীক্ষা করে জানে। একইভাবে এটি জানে যে এক্সপ্রেশনটিতে echo echoপ্রথম প্রতিধ্বনিটিকে একটি কমান্ড হিসাবে বিবেচনা করা উচিত এবং দ্বিতীয় প্রতিধ্বনিটিকে প্রথম প্রতিধ্বনির পরামিতি হিসাবে বিবেচনা করা উচিত।

ব্যাশে এটি খুব সহজ, যেহেতু { cmd; }স্পেস এবং সেমিকোলন থাকা উচিত। তবে, উদাহরণস্বরূপ zsh এ তাদের প্রয়োজন হয় না তবে {}শেলের প্রসঙ্গ বিশ্লেষণ করে এর বিষয়বস্তু দিয়ে কী করা উচিত তা বলতে সক্ষম হয়।

নিম্নোক্ত বিবেচনা কর:

alias 1..3=date
{ 1..3; }    #in bash
{1..3}       #in zsh

উভয়ই বর্তমান তারিখ ফেরত, তবে

echo {1..3}

ফিরে আসে 1 2 3কারণ শেল {}কমান্ডের জন্য একটি যুক্তিতে জানে echo, তাই প্রসারিত করা উচিত।


{অব্যক্ত স্থানের পরে ব্যাশে ব্রেস সম্প্রসারণ শুরু হয় না।
চোরোবা

@ ছোটোবা হ্যাঁ, এবং ঠিক পরেও নয় {। উদ্ধৃত স্থান আর কোথাও হতে পারে না কারণ শেল স্পেসে পুরো কমান্ড লাইন বিভক্ত করে।
jimmij

0

প্রথমত, যৌগিক বন্ধনীটি নিজেই একটি শব্দ এবং কমান্ড লাইনের প্রথম শব্দ হতে হবে:

echo { these braces are just words }

দ্বিতীয়ত, পৃথক ধনুর্বন্ধনী বিশেষ নয় (যেমন আপনি উপরে দেখতে পারেন)। খালি ধনুর্বন্ধনী এছাড়াও বিশেষ নয়:

echo {} # just the token {}: familiar from the find command

কমা ছাড়া কিছু হ'ল নিজেই

echo {abc} # just {abc}

এখানেই ক্রিয়া শুরু হয়।

echo {a,b} # braces disappear, a b results.

সুতরাং মূলত ব্রেস সম্প্রসারণের জন্য, আমাদের একটি শব্দ প্রয়োজন (হোয়াইটস্পেসে ক্ষেত্রগুলিতে বিভক্ত নয়) যার ভিতরে অন্তত একটি দৃষ্টান্ত {...}দেখা দেয় যার মধ্যে কমপক্ষে একটি কমা হয়।

এই করতে কমান্ড লাইনে প্রথম শব্দ, উপায় দ্বারা হতে:

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