Ashএ, বি, সি b কখন বাশে প্রসারিত হয়, কখন হয় না?


13

রয়েছে এমন একটি বাশ স্ক্রিপ্ট

for i in {a,b}-{1,2}; do
  echo $i;
done

কপি করে প্রিন্ট

a-1
a-2
b-1
b-2

মৃত্যুদন্ড কার্যকর করা হয় এটি আমি প্রত্যাশা করেছিলাম - {a,b}নির্মাণটি প্রসারিত হওয়ার সাথে সাথে।

তবে, যখন (অন্য) স্ক্রিপ্ট থাকে

v={a,b}-{1,2}
echo $v

এটি প্রিন্ট করে

{a,b}-{1,2}

যা আমি প্রত্যাশা করে তা নয়। আমি এটি মুদ্রণ আশা করি a-1 a-2 b-1 b-2। স্পষ্টতই, নির্মাণটি {a,b}প্রসারিত হয়নি।

আমি এটির মতো প্রসারিত করতে পারি

v=$(echo {a,b}-{1,2})

এই পর্যবেক্ষণগুলির ভিত্তিতে আমার দুটি প্রশ্ন রয়েছে: 1) {a,b}নির্মাণটি কখন প্রসারিত হবে? 2) $(echo {a,b}-{1,2})যখন প্রয়োজন হয় তখন কোনও প্রসারণ ট্রিগার করার পছন্দের উপায়?


1
এটি অন্ততপক্ষে এই সত্যের সাথে সামঞ্জস্যপূর্ণ যে আপনি কোনও সরল দিয়ে অ্যারে পরিবর্তনশীল করতে পারবেন না =। উদাহরণস্বরূপ, v=a-1 a-2কাজ করবে না।
গ্রোচমল

@ গ্রোচমাল - কারণ আপনি একটি স্কেলারের মান নির্ধারণ করছেন। v=a-1 a-2এর অর্থ assign 'a-1' to variable v and run 'a-2' v=(a-1 a-2)অ্যারেটি ভেরিয়েবলের জন্য বরাদ্দ করে vv+=(b-1 b-2)এটি সংযোজন।
ক্যাস

উত্তর:


15

ব্যাশ ম্যানুয়াল বলছেন যে:

SIMPLE COMMAND EXPANSION
When a simple command is executed, the shell performs the following
expansions, assignments, and redirections, from left to right.
[...]
4. The  text  after the = in each variable assignment undergoes tilde
   expansion, parameter expansion, command substitution, arithmetic
   expansion, and quote removal before being assigned to the variable.

ব্রেস সম্প্রসারণ তালিকায় নেই, সুতরাং এটি কার্যভারের জন্য সম্পাদিত হয় না v={a,b}-{1,2}। @ উইল্ডকার্ড দ্বারা উল্লিখিত হিসাবে, সহজ প্রসারটি v=a-1 v=b-1 ...যাইহোক নির্বোধ হবে।

এছাড়াও, কার্যকর করার সময় echo $v, নিম্নলিখিতটি প্রযোজ্য:

EXPANSION
Expansion is performed on the command line after it has been split
into words. [...]

The order of expansions is: brace expansion; tilde expansion, 
parameter and variable expansion, arithmetic expansion, and command
substitution (done in a left-to-right fashion); word splitting; and
pathname expansion.

পরিবর্তনশীল প্রসারণের আগে ব্রেস সম্প্রসারণ ঘটে, সুতরাং নির্ধারিত ধনুর্বন্ধনী $vপ্রসারিত হয় না।

তবে আপনি এই জাতীয় জিনিসগুলি করতে পারেন:

$ var_this=foo var_that=bar
$ echo $var_{this,that}
foo bar

এটির প্রসারিত করার কাজটি করা $(echo ...)উচিত যদি আপনার স্ট্রিংয়ের কোনও শ্বেত স্পেস না প্রসারিত হয় এবং এর ফলে শব্দ বিভাজনে সমস্যা হয় না। আপনি যদি পারেন তবে একটি অ্যারে ভেরিয়েবল ব্যবহার করা আরও ভাল উপায়।

উদাহরণস্বরূপ একটি অ্যারেতে প্রসারণটি সংরক্ষণ করুন এবং প্রসারিত মানগুলির সাথে কিছু কমান্ড চালান:

$ v=( {a,b}-{1,2} )
$ some_command "${v[@]}"

5

একটি আকর্ষণীয় বিষয়। নিম্নলিখিত সহায়কগুলি থেকে সম্ভবত সহায়ক সহায়ক man bash:

একটি পরিবর্তনশীল ফর্ম একটি বিবৃতি দ্বারা বরাদ্দ করা যেতে পারে

      নাম = [ মান ]

যদি মান দেওয়া হয়, পরিবর্তনশীল নাল স্ট্রিং নির্ধারিত হয়। সমস্ত মান টিলডে সম্প্রসারণ, প্যারামিটার এবং পরিবর্তনশীল সম্প্রসারণ, কমান্ড প্রতিস্থাপন, পাটিগণিতের সম্প্রসারণ এবং উদ্ধৃতি অপসারণের (নীচে সম্প্রসারণ দেখুন) সহকারে।

নোট করুন যে ব্রেস সম্প্রসারণ তালিকায় উল্লেখ করা হয়নি।

তবে এটি এখনও একটি প্রশ্ন রেখে যায়, যথা: শেলটি কীভাবে জানতে পারে যে এটি একটি পরিবর্তনশীল অ্যাসাইনমেন্ট এবং এভাবে ব্রেস সম্প্রসারণের বিষয় নয়? বা আরও স্পষ্টভাবে, পার্সিং সিকোয়েন্সটি এমন কোথায় স্পষ্ট এবং কোডিং করা হয়েছে যে শেলটি ব্রেস প্রসারণ পরিচালনা করার আগে ভেরিয়েবল অ্যাসাইনমেন্ট সনাক্ত করতে সংজ্ঞায়িত করা হয়? (এটি স্পষ্টতই কীভাবে bashকাজ করে তবে এটি বর্ণনা করার জন্য ডকুমেন্টেশনের সঠিক লাইনটি আমি খুঁজে পাইনি))


1
হয়তো এই ? "২. ভেরিয়েবল অ্যাসাইনমেন্ট বা পুনঃনির্দেশ নয় এমন শব্দগুলি প্রসারিত হয় (শেল প্রসারিত দেখুন)"
জেফ শ্যাচলার

@ জেফ শ্যাচলার, আপনি সঠিক বলেছেন। প্রকৃতপক্ষে "সিম্পল কম্যান্ড এক্সপ্যান্সেশন" ( LESS=+/SIMPLE man bash) বিভাগটি পড়ার মাধ্যমে এই প্রশ্নের সর্বোত্তম জবাব দেওয়া হয়েছে ।
ওয়াইল্ডকার্ড

0

আমার লিলের জ্ঞান অনুসারে কমান্ডের সাথে সরাসরি প্রতিধ্বনিত করা বা ব্যবহার করা হলে {a, b, c expand প্রসারিত হয় যেমন: mkdir ~ / {a, b, c}, তবে যখন এটি একটি পরিবর্তনশীলতে সেট করা থাকে তার আগে মূল্যায়ন করা উচিত এটি প্রতিধ্বনিত করা বা তর্ক হিসাবে ব্যবহার করা!

u@h:~$ echo {a,b}-{1,2}
a-1 a-2 b-1 b-2
u@h:~$ v={a,b}-{1,2}
u@h:~$ echo $v
{a,b}-{1,2}
u@h:~$ eval echo $v
a-1 a-2 b-1 b-2

আপনার যেহেতু আলফা ক্রমে "a" এর পরে "b" রয়েছে এবং "1" এর পরে ডিক্স ক্রমে "2" রয়েছে [0-9]: আপনি ডাবল পিরিয়ড ব্যবহার করতে পারেন ".." কমাতে উত্সাহিত ", "

u@h:~$ echo {a..b}-{1..2}
a-1 a-2 b-1 b-2
u@h:~$ v={a..b}-{1..2}
u@h:~$ echo $v
{a..b}-{1..2}
u@h:~$ eval echo $v
a-1 a-2 b-1 b-2

1
এ প্রশ্ন উঠছে কেন vহয় নি সেট আক্ষরিক STRING "A-1 একটি-2 খ -1 B-2" করা হয়েছে। অথবা কম্যান্ডটি টাইপ করলে কমপক্ষে কোনও ত্রুটি কেন ছুঁড়ে দেওয়া হয়নি: v=a-1 v=a-2 v=b-1 v=b-2(যা আপনি আশা করতে পারেন যে পরিবর্তনশীল কার্যটি প্রসারিত হবে)। এটি একটি ভাল প্রশ্ন; এটি সত্যই এর উত্তর দেয় না।
ওয়াইল্ডকার্ড

@ স্যাটোক্যাটসুরা, "ওয়াইল্ডকার্ড সম্প্রসারণ" এর অর্থ কী? এখানে প্যারামিটার সম্প্রসারণ, পথের নাম সম্প্রসারণ এবং ধনুর্বন্ধনী প্রসার রয়েছে which যার মধ্যে আপনি উল্লেখ করতে পারেন, এবং সেগুলির সবকটি আলাদা। বা আপনি কি শব্দ বিভাজন বলতে চেয়েছিলেন?
ওয়াইল্ডকার্ড

0

ব্যাশে কোনও ভেরিয়েবলকে বরাদ্দ করা অভিব্যক্তিটি প্রসারিত করে না।

এই ছোট স্ক্রিপ্টের জন্য, এক্স এতে থাকবে "*"না এবং এর সম্প্রসারণ নয় "*":

#!/bin/bash
x=*
echo "$x"

যাইহোক, কিছু মান প্রসারিত হয়, রেফ। ইলকচু থেকে সুন্দর উত্তর।

মূল্যায়ন করা হয় যখন অভিব্যক্তি প্রসারিত হয়।

এটার মত:

x=$(echo *)        # <-- evaluation of "*"
echo "$x"

বা এই মত:

x=*
echo $x            # <-- evaluation of $x

বা এই মত:

x=*
eval echo "$x"     # <-- evaluation of `echo *`

ট্রিগারিং $()মোটামুটি সাধারণ এবং আমি মনে করি এটির চেয়ে বেশি পছন্দ করা হয়েছে evalতবে ভেরিয়েবলটি কোনও কমান্ডে ব্যবহার না করা অবধি মূল্যায়নকে ট্রিগার না করা সবচেয়ে ভাল।

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