লিনাক্স ব্যাশ: একাধিক ভেরিয়েবল অ্যাসাইনমেন্ট


121

লিনাক্স ব্যাশে পিএইচপি-তে নিম্নলিখিত কোডের অনুরূপ কিছু উপস্থিত রয়েছে:

list($var1, $var2, $var3) = function_that_returns_a_three_element_array() ;

অর্থাত্ আপনি একটি বাক্যে 3 টি ভিন্ন ভেরিয়েবলের সাথে সম্পর্কিত মান নির্ধারণ করেন।

আসুন ধরা যাক আমার কাছে বাশ ফাংশন রয়েছে myBashFuntionযা "কিউয়ার্ট্যাসিডেফজি জেডএক্সসিভিবি" স্ট্রিংকে স্টডআউট করতে লিখেছে। এর মতো কিছু করা কি সম্ভব:

(var1 var2 var3) = ( `myBashFuntion param1 param2` )

সমান চিহ্নের বাম অংশটি অবশ্যই বৈধ সিনট্যাক্স নয়। আমি যা চাইছি তা বোঝানোর চেষ্টা করছি।

যদিও কাজ করে তা নিম্নলিখিত:

array = ( `myBashFuntion param1 param2` )
echo ${array[0]} ${array[1]} ${array[2]}

তবে একটি সূচকযুক্ত অ্যারে প্লেইন ভেরিয়েবল নামের মতো বর্ণনামূলক নয়।
তবে, আমি কেবল এটি করতে পারি:

var1 = ${array[0]} ; var2 = ${array[1]} ; var3 = ${array[2]}

তবে এগুলি আরও 3 টি বিবৃতি যা আমি এড়াতে পছন্দ করি।

আমি কেবল একটি শর্টকাট বাক্য গঠন খুঁজছি। এটা কি সম্ভব?

উত্তর:


222

আমার মনে প্রথম জিনিসটি আসে:

read -r a b c <<<$(echo 1 2 3) ; echo "$a|$b|$c"

আউটপুট, আশ্চর্যজনকভাবে হয়

1|2|3

4
যদি প্রথম ভেরিয়েবলটিতে একটি জায়গা থাকে তবে কী এটির কাজ করার উপায় আছে?
রুসেন্ট 88

7
@ মিশেল ইউজিং read -d "\n" v1 v2 <<<$(cmd)পুরোপুরি কাজ করে । ধন্যবাদ!
রুসেন্ট

1
@ লাইনেথের্টন, ভালো কথা, যদিও আমি নিশ্চিত নই যে একজনের ইকো কমান্ডের রিটার্নের স্ট্যাটাসের দরকার আছে কিনা :-) আমি মনে করি যে উত্তর বাক্সটি লেখার সময় এই বাক্য গঠনটি সমর্থন করে কম ছিল (যেমন ডিফল্ট হিসাবে ইনস্টল করা হয়েছিল), যদিও আমি আমি 100% নিশ্চিত নই।
মাইকেল ক্রেলিন - হ্যাকার

4
@ মাইকেল ক্রেলিন-হ্যাকার নিশ্চিত, এর রিটার্নের স্ট্যাটাসটি echoঅর্থহীন, তবে আমি এই কৌশলটি ব্যবহার করেছিলাম কোনও স্ক্রিপ্ট থেকে একাধিক মূল্য ফেরত দেওয়ার জন্য যা আমি প্রত্যাবর্তনের অবস্থা সম্পর্কে যত্নবান ছিলাম। আমি ভেবেছিলাম আমি আমার অনুসন্ধানগুলি ভাগ করব।
লি নেদারটন

1
সুরক্ষার জন্য আপনার ব্যবহার করা উচিত read -r:do not allow backslashes to escape any characters
টম হেল

18

আমি মানগুলি একটি অ্যারেতে নির্ধারণ করতে চেয়েছিলাম। সুতরাং, মাইকেল ক্রেলিনের পদ্ধতির প্রসারিত করে , আমি এটি করেছি:

read a[{1..3}] <<< $(echo 2 4 6); echo "${a[1]}|${a[2]}|${a[3]}"

যা ফলন:

2|4|6 

প্রত্যাশিত.


2
একটি অ্যারেতে মানগুলি রাখার জন্য ইতিমধ্যে একটি সহজ সমাধান রয়েছে যা আমি প্রশ্নের মধ্যে উল্লেখ করেছি:a=( $(echo 2 4 6) ) ; echo ${a[0]} ${a[1]} ${a[2]}
getFree

হ্যাঁ, আমি এটি উপেক্ষা করেছি। তবে আমি যুক্তি দিয়ে বলব যে আমার পরামর্শটি বৃহত্তর অ্যারে দেওয়ার ক্ষেত্রে আরও উপযুক্ত।
শনি

@ সাউন্ড্রে আপনার সমাধানটি প্রসারণ এবং একটি স্ট্রাস্টিং ব্যবহার করে, ব্যাশ এটি হ'ল এটি আমার পক্ষে সন্দেহ হয় যে এটি সেই দৃশ্যে ভাল অভিনয় করবে (তবে আমি পরীক্ষা করিনি)।
ক্যামিলো মার্টিন

সুরক্ষার জন্য আপনার ব্যবহার করা উচিত read -r:do not allow backslashes to escape any characters
টম হেল

5

আমি মনে করি এটি সাহায্য করতে পারে ...

আমার স্ক্রিপ্টগুলিতে ব্যবহারকারীর ইনপুটেটেড তারিখগুলি (মিমি / ডিডি / ইয়াই) ভাঙ্গার জন্য, আমি দিন, মাস এবং বছরটিকে একটি অ্যারেতে সঞ্চয় করি এবং তারপরে মানগুলি পৃথক ভেরিয়েবলগুলিতে নিম্নরূপে রাখি:

DATE_ARRAY=(`echo $2 | sed -e 's/\// /g'`)
MONTH=(`echo ${DATE_ARRAY[0]}`)
DAY=(`echo ${DATE_ARRAY[1]}`)
YEAR=(`echo ${DATE_ARRAY[2]}`)

4 টি সাবহেল প্লাস অতিরিক্ত শ্যাড প্রক্রিয়া কেন এড়াবেন না, এবং কেবল সমস্ত লাইনেই করুন:IFS=/ read -r m d y < <(echo 12/29/2009)
অমিত নাইডু

5

কখনও কখনও আপনি মজার কিছু করতে হবে। ধরা যাক আপনি একটি কমান্ড থেকে পড়তে চান (উদাহরণস্বরূপ SDGuero দ্বারা তারিখের উদাহরণ) তবে আপনি একাধিক কাঁটাচাটি এড়াতে চান।

read month day year << DATE_COMMAND
 $(date "+%m %d %Y")
DATE_COMMAND
echo $month $day $year

আপনি রিড কমান্ডটি পাইপ করতে পারেন তবে তারপরে আপনাকে একটি সাব-শেলের মধ্যে ভেরিয়েবলগুলি ব্যবহার করতে হবে:

day=n/a; month=n/a; year=n/a
date "+%d %m %Y" | { read day month year ; echo $day $month $year; }
echo $day $month $year

ফলাফল স্বরূপ...

13 08 2013
n/a n/a n/a

readকমান্ড একটি subshell ঘটতে না কারণ ধনুর্বন্ধনী, এটা কারণ আপনার নল ডান দিকে পঠিত কমান্ড পেয়েছেন। readআপনার বর্তমান শেলটিতে কমান্ডটি চালানো দরকার যা আপনি করতে পারেনread day month year <<< `date "+%d %m %Y"`
বায়ুসংস্থান

না - read ঘটে তবে পাইপলাইনটির সাবশেল শেষ হয়ে গেলে ভেরিয়েবলগুলির স্কোপটি সুযোগের বাইরে চলে যায়।
ওথিয়াস

1
আমার মন্তব্যটি কেন সাবসেলের মাধ্যমে পড়ার কারণ সম্পর্কে ছিল এবং আমি বুঝতে পেরেছিলাম যে আপনি যা লিখেছেন তা ভুলভাবে লিখেছি। আমি ভেবেছিলাম আপনি বোঝাতে চেয়েছিলেন যে সাবসেল তৈরি করা হয়েছিল কারণ আপনি যৌগিক বিবরণের চারপাশে কোঁকড়ানো ধনুর্বন্ধনী ব্যবহার করেছেন। কিন্ত! আপনি যে উদাহরণটি দিয়েছেন তার কারণটি ছিল কাঁটাচামচ এড়ানো, এবং তবে সাব্হেল কাঁটাচামচও কী হবে না?
বায়ুসংক্রান্ত

প্রথম উদাহরণে ঠিক একটি কাঁটাচামচ প্রয়োজন: যাতে বাশ তারিখের আদেশটি প্রবর্তন করতে পারে। দ্বিতীয় উদাহরণে, আপনি তারিখ এবং আপনার সাব-শেলের মধ্যে একটি পাইপলাইন সেট আপ করেছেন। আমি মনে করি এই দিনগুলিতে বাশ আসলে সাবসেলের মধ্যে কাঁটাচামচ না করার পক্ষে যথেষ্ট চালাক তবে আমি সে সম্পর্কে নিশ্চিত নই। যে কোনও হারে, দেখে মনে হচ্ছে এটি :)
ওথিয়াস

0

ওরিলির বাশ কুকবুকের অধ্যায় 5, একটি পরিবর্তনশীল অ্যাসাইনমেন্টে প্রয়োজনীয়তার কারণগুলি নিয়ে আলোচনা করে যে '=' চিহ্নের চারপাশে কোনও ফাঁকা স্থান নেই be

MYVAR="something"

কমান্ডের নাম এবং একটি ভেরিয়েবলের (যেখানে '=' একটি বৈধ যুক্তি হতে পারে) এর মধ্যে পার্থক্য করার সাথে ব্যাখ্যাটির কিছু যোগ রয়েছে।

এটি সমস্ত ঘটনার পরে ন্যায়সঙ্গত করার মতো বলে মনে হয় তবে কোনও অবস্থাতেই ভেরিয়েবলের তালিকা নির্ধারণের কোনও পদ্ধতির উল্লেখ নেই।


হ্যা আমি জানি. আমি কেবল পঠনযোগ্যতার জন্য এখানে এবং সেখানে অতিরিক্ত স্থান যুক্ত করেছি
getFree

আসলে এটি একটি দুর্বল প্রেরণা: ' ;' যদি একটি বৈধ যুক্তি হয় তবে কী হবে? যখন আমি ls ; cdএটি লিখি তখনও কল করে lsএবং cdফাঁকা স্থান সত্ত্বেও। যদি আমি ডায়রেক্টরিগুলি তালিকাবদ্ধ করতে চাই ;এবং cdআমি কেবল টাইপ করতে পারি ls ';' cd
পিটারনয়েটস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.