বাশ এবং এর সাধারণ ব্যবহারগুলিতে eval কমান্ড


165

বাশ ম্যান পৃষ্ঠাগুলি পড়ার পরে এবং এই পোস্টে শ্রদ্ধার সাথে ।

evalকমান্ডটি ঠিক কী করে এবং এটির সাধারণ ব্যবহারগুলি কী তা বুঝতে আমার এখনও সমস্যা হচ্ছে । উদাহরণস্বরূপ যদি আমরা এটি করি:

bash$ set -- one two three  # sets $1 $2 $3
bash$ echo $1
one
bash$ n=1
bash$ echo ${$n}       ## First attempt to echo $1 using brackets fails
bash: ${$n}: bad substitution
bash$ echo $($n)       ## Second attempt to echo $1 using parentheses fails
bash: 1: command not found
bash$ eval echo \${$n} ## Third attempt to echo $1 using 'eval' succeeds
one

এখানে ঠিক কী ঘটছে এবং ডলার সাইন এবং ব্যাকস্ল্যাশ কীভাবে সমস্যার মধ্যে রয়েছে?


1
রেকর্ডের জন্য, দ্বিতীয় প্রচেষ্টা কাজ করে। একটি subhell $($n)চালায় $n। এটি কমান্ডটি চালানোর চেষ্টা 1করে যা বিদ্যমান নেই।
মার্টিন উইকম্যান

1
@ মার্টিন উইকম্যান তবে প্রয়োজনটি echo $1শেষ পর্যন্ত চালানো উচিত , তা নয় 1। আমি মনে করি না এটি সাবসেল ব্যবহার করে করা যেতে পারে।
হরি মেনন


1
@ রাজে টুডাস্ট: আমি বিশ্বাস করি না যে তিনি পরামর্শ দিয়েছিলেন যে এটি সাবসেল দিয়ে চালানো যেতে পারে, তবে বরং ব্যাখ্যা করেছেন যে ওপি তালিকাভুক্ত 5 তম কমান্ড কেন কাজ করে না।
jedwards

উত্তর:


196

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

${$n}ব্যাশে সিনট্যাক্স ত্রুটি। ধনুর্বন্ধনীগুলির অভ্যন্তরে, আপনার কয়েকটি সম্ভাব্য উপসর্গ এবং প্রত্যয় সহ কেবলমাত্র একটি পরিবর্তনশীল নাম থাকতে পারে তবে আপনি স্বেচ্ছায় বাশ বাক্য গঠন করতে পারবেন না এবং বিশেষত আপনি পরিবর্তনশীল প্রসারণ ব্যবহার করতে পারবেন না। এখানে বলার একটি উপায় আছে "ভেরিয়েবলের মান যার নাম এই পরিবর্তনশীল", যদিও:

echo ${!n}
one

$(…)একটি সাবশেলে (অর্থাত্ একটি পৃথক প্রক্রিয়ায় যা বর্তমান সেটিংস থেকে চলক মানগুলির মতো সমস্ত সেটিংস উত্তরাধিকার সূত্রে প্রাপ্ত) পৃথক কমান্ড চালায় এবং এর আউটপুট সংগ্রহ করে। সুতরাং শেল কমান্ড হিসাবে echo $($n)চালায় $nএবং এর আউটপুট প্রদর্শন করে। যেহেতু $nমূল্যায়ন করা হয় 1, $($n)কমান্ড চালানোর চেষ্টা করে 1যা বিদ্যমান নেই।

eval echo \${$n}পরামিতি চালিত eval। প্রসারণের পরে, পরামিতিগুলি হয় echoএবং ${1}। সুতরাং eval echo \${$n}কমান্ড রান echo ${1}

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

$ ls
file1 file2 otherfile
$ set -- 'f* *'
$ echo "$1"
f* *
$ echo $1
file1 file2 file1 file2 otherfile
$ n=1
$ eval echo \${$n}
file1 file2 file1 file2 otherfile
$eval echo \"\${$n}\"
f* *
$ echo "${!n}"
f* *

evalখুব প্রায়ই ব্যবহার করা হয় না। কিছু শেলের মধ্যে, সর্বাধিক সাধারণ ব্যবহারটি এমন একটি ভেরিয়েবলের মান অর্জন করা হয় যার নাম রানটাইম পর্যন্ত জানা যায় না। ব্যাশে, ${!VAR}সিনট্যাক্সের জন্য এটি প্রয়োজনীয় ধন্যবাদ নয় । evalঅপারেটর, সংরক্ষিত শব্দ, ইত্যাদি সমন্বিত একটি দীর্ঘ কমান্ড তৈরি করার দরকার পরে এখনও দরকারী


উপরের আমার মন্তব্য সম্পর্কে, খ্রিস্টান কয়টি "পাস" করে?
kstratis

@ Konos5 কি মন্তব্য? evalএকটি স্ট্রিং (যা নিজেই পার্সিং এবং মূল্যায়নের ফলাফল হতে পারে) গ্রহণ করে এবং এটিকে কোড স্নিপেট হিসাবে ব্যাখ্যা করে।
গিলস 'তাই খারাপ হওয়া বন্ধ করুন'

রাজে টুস্টের উত্তরে আমি একটি মন্তব্য রেখেছি। আমি এখন বিশ্বাস করি যে ইওল বেশিরভাগ ক্ষেত্রে অবহিতকরণের উদ্দেশ্যে ব্যবহৃত হয়। আমি যদি এভাল ইকো টাইপ করি \ $ {$ n} আমি একটি পাই। তবে আমি যদি প্রতিধ্বনি লিখি \ $ {$ n} আমি পাই \ $ {1}} আমি বিশ্বাস করি এভালের "দুই-পাস" পার্সিংয়ের কারণে এটি ঘটছে। আমি এখন ভাবছি অতিরিক্ত আই = এন ডিক্লেয়ারেশন ব্যবহার করে যদি আমাকে ট্রিপল ডিरेফারেন্সের প্রয়োজন হয় তবে কী হবে। এই ক্ষেত্রে Raze2dust অনুসারে আমার কেবল একটি অতিরিক্ত ক্রম রাখা দরকার। তবে আমি বিশ্বাস করি যে এর চেয়ে ভাল উপায় হওয়া উচিত ... (এটি সহজেই
বিশৃঙ্খলা

@ Konos5- কে আমি ব্যবহার করব না eval eval। আমি কখনও প্রয়োজন অনুভব মনে করতে পারি না। আপনি কি সত্যিই দুই পারে এমন evalপাস, একটি অস্থায়ী ভেরিয়েবল ব্যবহার, এটা ডিবাগ করার সহজ হয়ে উঠবে: eval tmp="\${$i}"; eval x="\${$tmp}"
গিলস 'খারাপ হয়ে যাওয়া বন্ধ করুন'

1
@ কনোস 5 "দুবার পার্সড" করা সামান্য বিভ্রান্তিকর। বিভিন্ন সম্প্রসারণ থেকে সুরক্ষিত বাশে আক্ষরিক স্ট্রিং আর্গুমেন্ট নির্দিষ্টকরণের অসুবিধার কারণে কিছু লোক এটি বিশ্বাস করতে পরিচালিত হতে পারে। evalকেবল একটি স্ট্রিংয়ে কোড নেয় এবং সাধারণ নিয়ম অনুসারে এটিকে মূল্যায়ন করে। প্রযুক্তিগতভাবে, এটি এমনকি সঠিক নয়, কারণ কয়েকটি কোণার কেস রয়েছে যেখানে বাশ এমনকি বিভক্তির যুক্তিগুলিতেও বিস্তৃতকরণ না করার জন্য পার্সিং করে - তবে এটি একটি খুব অস্পষ্ট প্রবণতা যা আমি সন্দেহ করি যে সম্পর্কে কেউ জানেন knows
ormaaj

39

কেবল "মৃত্যুদন্ডের পূর্বে আরও একবার আপনার অভিব্যক্তিটি মূল্যায়ন করা" হিসাবে খোলাসা ভাবুন

eval echo \${$n}echo $1মূল্যায়ন প্রথম দফার পরে হয়ে যায় । তিনটি পরিবর্তন লক্ষ্য করুন:

  • \$হয়ে ওঠে $(ব্যাকস্ল্যাশ প্রয়োজন হয়, অন্যথায় এটি নির্ণয় করা চেষ্টা করে ${$n}নাম একটি পরিবর্তনশীল যার মানে {$n}, যা অনুমোদিত নয়)
  • $n মূল্যায়ন করা হয়েছিল 1
  • evalলীন

দ্বিতীয় রাউন্ডে, এটি মূলত echo $1যা সরাসরি সম্পাদন করা যেতে পারে।

সুতরাং eval <some command>প্রথমে মূল্যায়ন করা হবে <some command>(এখানে মূল্যায়ন করে আমার অর্থ পরিবর্তনশীলগুলি পরিবর্তিত হওয়া, পালানো অক্ষরগুলি যথাযথ ইত্যাদি দিয়ে প্রতিস্থাপন করা হবে) এবং তারপরে আবার ফলাফলের এক্সপ্রেশনটি চালানো হবে।

evalআপনি যখন পরিবর্তনশীল পরিবর্তনশীল তৈরি করতে চান বা বিশেষত এর মতো পড়ার জন্য ডিজাইন করা প্রোগ্রামগুলি থেকে আউটপুটগুলি পড়তে চান তখন ব্যবহৃত হয়। উদাহরণের জন্য http://mywiki.wooledge.org/BashFAQ/048 দেখুন । লিঙ্কটিতে কিছু সাধারণ উপায় রয়েছে যা evalব্যবহার করা হয় এবং এর সাথে যুক্ত ঝুঁকিগুলিও রয়েছে।


3
প্রথম বুলেট জন্য একটা নোট হিসাবে, ${VAR}সিনট্যাক্স হয় যখন কোন অস্পষ্টতা (হয় অনুমোদিত, এবং পছন্দসই $VAR == $V, দ্বারা অনুসরণ ARবা $VAR == $VAঅনুসরণ R)। ${VAR}সমতূল্য $VAR। আসলে, এর এর পরিবর্তনশীল নাম $nঅনুমোদিত নয়।
jedwards

2
eval eval echo \\\${\${$i}}একটি ট্রিপল বিন্যাস করবে। এটি করার সহজ উপায় আছে কিনা তা সম্পর্কে আমি নিশ্চিত নই। এছাড়াও, আমার মেশিনে \${$n}সূক্ষ্ম (প্রিন্ট one) কাজ করে ..
হরি মেনন

2
@ Konos5 echo \\\${\${$i}}কপি করে প্রিন্ট \${${n}}। $ {1} এর eval echo \\\${\${$i}}সমতুল্য ইওল ইকো \\\ $ {\ $ {{$ i}} `এর সমতুল্য এবং মুদ্রণযোগ্য । echo \${${n}}`` and prints . eval echo ${1}one
গিলস 'তাই খারাপ হওয়া বন্ধ করুন'

2
@ কনোস 5 একই লাইন ধরে ভাবুন - প্রথম - ` escapes the second one, and the third এর $পরে পালিয়ে যায় । সুতরাং এটি \${${n}}এক
হরি মেনন

2
@ কোনোস 5 বাম থেকে ডান হ'ল উদ্ধৃতি এবং ব্যাকস্ল্যাশ পার্সিংয়ের জন্য ভাবার সঠিক উপায়। প্রথমে \\ একটি ব্যাকস্ল্যাশ ফলন। তারপরে \$এক ডলার ফলন হচ্ছে। ইত্যাদি।
গিলস 'তাই খারাপ হওয়া বন্ধ করুন'

25

আমার অভিজ্ঞতায়, ইভালটির একটি "সাধারণ" ব্যবহার চলমান কমান্ডগুলির জন্য যা পরিবেশের ভেরিয়েবলগুলি সেট করতে শেল কমান্ড উত্পন্ন করে।

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

স্পষ্ট না করে, আপনাকে স্টডআউটকে একটি টেম্প ফাইলটিতে পুনর্নির্দেশ করতে হবে, টেম্প ফাইলটি উত্স করতে হবে এবং তারপরে এটি মুছতে হবে। ওভাল দিয়ে, আপনি ঠিক করতে পারেন:

eval "$(script-or-program)"

উল্লেখ্য, উদ্ধৃতিগুলি গুরুত্বপূর্ণ। এটি (স্বীকৃত) উদাহরণটি ধরুন:

# activate.sh
echo 'I got activated!'

# test.py
print("export foo=bar/baz/womp")
print(". activate.sh")

$ eval $(python test.py)
bash: export: `.': not a valid identifier
bash: export: `activate.sh': not a valid identifier
$ eval "$(python test.py)"
I got activated!

সাধারণ সরঞ্জামগুলির কোনও উদাহরণ আছে যা এটি করে? এই সরঞ্জামটি নিজেই শেল কমান্ডগুলির একটি সেট তৈরি করার উপায় রয়েছে যা evভালকে দেওয়া যেতে পারে?
জোয়াকিম এরদফেল্ট

@ জোয়াকিম আমি এটি করে এমন কোনও ওপেনসোর্স সরঞ্জাম সম্পর্কে জানি না, তবে আমি যেখানে কাজ করেছি সেখানে কিছু ব্যক্তিগত স্ক্রিপ্টগুলিতে এটি ব্যবহার করা হয়েছিল। আমি স্রেফ xampp দিয়ে এই কৌশলটি ব্যবহার শুরু করেছি। অ্যাপাচি .conf ফাইলগুলি পরিবেশের ভেরিয়েবলগুলি প্রসারিত করে ${varname}। পরিবেশের ভেরিয়েবল দ্বারা প্যারামিটারাইজড কয়েকটি জিনিস দিয়ে আমি বিভিন্ন আলাদা সার্ভারে অভিন্ন .conf ফাইলগুলি ব্যবহার করা সুবিধাজনক বলে মনে করি। সিস্টেমের চারপাশে exportঝাঁকুনি দেয় এবং .conf ফাইলগুলির জন্য ভেরিয়েবল সংজ্ঞায়িত করার জন্য ব্যাশ স্টেটমেন্ট আউটপুট করে এমন স্ক্রিপ্টের সাহায্যে এই জাতীয় ইওলগুলি সম্পাদন করার জন্য আমি অপ্ট / ল্যাম্প / এক্সএ্যাম্প্প (যা অ্যাপাচি শুরু করে) সম্পাদনা করেছি ।
sootsnoot

@ জোয়াকিম বিকল্পটি প্রায় একই পোকার উপর ভিত্তি করে টেমপ্লেট থেকে প্রভাবিত প্রতিটি .conf ফাইল তৈরির জন্য একটি স্ক্রিপ্ট থাকবে। আমার উপায় সম্পর্কে আমার আরও ভাল লাগার বিষয় হ'ল / opt / lampp / xampp না গিয়ে অ্যাপাচি শুরু করা বাসি আউটপুট স্ক্রিপ্টগুলি ব্যবহার করে না, বরং এটি শুরু করতে ব্যর্থ হয় কারণ পরিবেশের ভেরিয়েবলগুলি কোনও ক্ষেত্রেই প্রসারিত হয় না এবং অবৈধ নির্দেশিকা তৈরি করে।
sotsnoot

@ অ্যান্টনি সটাইল আমি দেখতে পেয়েছি আপনি $ (স্ক্রিপ্ট-বা-প্রোগ্রাম) এর আশেপাশে উদ্ধৃতি যুক্ত করার জন্য উত্তরটি সম্পাদনা করেছেন, একথা জানিয়েছে যে একাধিক কমান্ড চালানোর সময় সেগুলি গুরুত্বপূর্ণ ছিল। আপনি দয়া করে একটি উদাহরণ সরবরাহ করতে পারেন - নিম্নলিখিত foo.sh এর স্টাডাউটে আধা-কোলন বিচ্ছিন্ন কমান্ডগুলির সাথে সূক্ষ্মভাবে কাজ করে: ইকো '#! / বিন / বাশ'> foo.sh; প্রতিধ্বনি 'প্রতিধ্বনি "প্রতিধ্বনি"; প্রতিধ্বনি-এনবি; ইকো-এন সি "" >> foo.sh; chmod 755 foo.sh; eval $ (./ foo.sh)। এটি স্টটআউটে এ বি সি তৈরি করে। চলমান ./foo.sh উত্পাদন করে: প্রতিধ্বনি -na; প্রতিধ্বনি -nb; প্রতিধ্বনি-সিএনএস
sootsnoot করুন

1
সাধারণ সরঞ্জাম যা উদাহরণস্বরূপ ব্যবহার করে, উদাহরণস্বরূপ, পায়ানভ দেখুন । পাইয়ানভ আপনাকে পাইথনের একাধিক সংস্করণের মধ্যে সহজেই স্যুইচ করতে দেয়। আপনি eval "$(pyenv init -)"আপনার .bash_profile(বা অনুরূপ) শেল কনফিগারেশন ফাইলটি রেখেছেন । এটি একটি সামান্য শেল স্ক্রিপ্ট তৈরি করে তারপরে এটি বর্তমান শেলটিতে মূল্যায়ন করে।
জেরি 101

10

খোলামেলা বিবৃতি শেলকে আদেশ দেয় যে ওভালের আর্গুমেন্টকে কমান্ড হিসাবে গ্রহণ করবে এবং সেগুলি কমান্ড-লাইনের মাধ্যমে চালিত করবে। এটি নীচের মতো পরিস্থিতিতে কার্যকর:

আপনার স্ক্রিপ্টে আপনি যদি কোনও কমান্ডকে ভেরিয়েবলের মধ্যে সংজ্ঞায়িত করে থাকেন এবং পরে আপনি সেই কমান্ডটি ব্যবহার করতে চান তবে আপনার উচিত eval:

/home/user1 > a="ls | more"
/home/user1 > $a
bash: command not found: ls | more
/home/user1 > # Above command didn't work as ls tried to list file with name pipe (|) and more. But these files are not there
/home/user1 > eval $a
file.txt
mailids
remote_cmd.sh
sample.txt
tmp
/home/user1 >

4

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


বাশ evalবিবৃতি আপনাকে আপনার বাশ স্ক্রিপ্ট দ্বারা গণনা করা বা অর্জিত কোডের লাইনগুলি সম্পাদন করতে দেয়।

সম্ভবত সবচেয়ে সহজ উদাহরণটি হ'ল বাশ প্রোগ্রাম যা একটি টেক্সট ফাইল হিসাবে অন্য একটি বাশ স্ক্রিপ্ট খুলবে, পাঠ্যের প্রতিটি লাইন পড়বে এবং evalসেগুলি কার্যকর করার জন্য ব্যবহার করবে। এটি মূলত বাশ sourceস্টেটমেন্টের মতোই আচরণ , যা আমদানি করা স্ক্রিপ্টের সামগ্রীতে কোনও ধরণের রূপান্তর (যেমন ফিল্টারিং বা প্রতিস্থাপন) সম্পাদন করা প্রয়োজন না হলে এটিই ব্যবহার করবে।

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

evalধারণাগতভাবে সহজ। তবে, বাশ ভাষার কঠোর বাক্য গঠন এবং ব্যাশ ইন্টারপ্রেটারের পার্সিং ক্রমটি সংজ্ঞায়িত হতে পারে এবং evalক্রিপ্টিক এবং ব্যবহার করতে বা বুঝতে অসুবিধে হয়। এখানে প্রয়োজনীয়:

  1. আর্গুমেন্টটি পাস করা evalএকটি স্ট্রিং এক্সপ্রেশন যা রানটাইম সময়ে গণনা করা হয়। আপনার স্ক্রিপ্টে কোডের evalএকটি আসল লাইন হিসাবে এর যুক্তির চূড়ান্ত বিশ্লেষণের ফলাফল কার্যকর করবে ।

  2. সিনট্যাক্স এবং পার্সিং অর্ডার কঠোর। ফলাফলটি যদি আপনার স্ক্রিপ্টের স্কোপ অনুযায়ী ব্যাশ কোডের একটি কার্যকরযোগ্য লাইন না হয় তবে প্রোগ্রামটি evalবিবৃতিতে ক্র্যাশ করবে কারণ এটি আবর্জনা চালানোর চেষ্টা করে।

  3. পরীক্ষা করার সময় আপনি evalবিবৃতিটি প্রতিস্থাপন করতে পারেন echoএবং কী প্রদর্শিত হয় তা দেখুন। এটি যদি বর্তমান প্রসঙ্গে বৈধ কোড হয় তবে এটিকে চালানো কার্যকর হবে eval


নিম্নলিখিত উদাহরণগুলি স্পষ্ট করতে সহায়তা করতে পারে কীভাবে eval কাজ করে ...

উদাহরণ 1:

eval 'সাধারণ' কোডের সামনে বিবৃতি একটি এনওপি

$ eval a=b
$ eval echo $a
b

উপরের উদাহরণে, প্রথম evalবিবৃতিগুলির কোনও উদ্দেশ্য নেই এবং এটি নির্মূল করা যায়। evalপ্রথম লাইনে অর্থহীন কারণ কোডটির কোনও গতিশীল দিক নেই, অর্থাত্ এটি ইতিমধ্যে ব্যাশ কোডের চূড়ান্ত লাইনগুলিতে পার্স করা হয়েছে, সুতরাং এটি ব্যাশ স্ক্রিপ্টের কোডের সাধারণ বিবৃতি হিসাবে অভিন্ন। ২ evalয়টি অর্থহীন, কারণ, যদিও $aএটির আক্ষরিক স্ট্রিং সমতুল্যে রূপান্তরকারী পদক্ষেপ রয়েছে তবুও কোনও দিকনির্দেশ নেই (উদাহরণস্বরূপ প্রকৃত বাশ বিশেষ্য বা ব্যাশ-অধিষ্ঠিত স্ক্রিপ্ট ভেরিয়েবলের স্ট্রিং মানের মাধ্যমে কোনও রেফারেন্সিং নেই ), সুতরাং এটি অভিন্নভাবে আচরণ করবে evalউপসর্গ ছাড়াই কোডের লাইন হিসাবে ।



উদাহরণ 2:

স্ট্রিংয়ের মান হিসাবে পাস করা ভের নাম ব্যবহার করে ভার অ্যাসাইনমেন্ট সম্পাদন করুন।

$ key="mykey"
$ val="myval"
$ eval $key=$val
$ echo $mykey
myval

আপনি যদি হন echo $key=$val, আউটপুটটি হবে:

mykey=myval

এটি , স্ট্রিং পার্সিংয়ের চূড়ান্ত ফলাফল হ'ল ইলাল দ্বারা মৃত্যুদন্ড কার্যকর করা হবে, অতএব শেষে প্রতিধ্বনি বিবরণের ফলাফল ...



উদাহরণ 3:

উদাহরণ 2-এ আরও বেশি দিকনির্দেশ যুক্ত করা হচ্ছে

$ keyA="keyB"
$ valA="valB"
$ keyB="that"
$ valB="amazing"
$ eval eval \$$keyA=\$$valA
$ echo $that
amazing

পূর্ববর্তী উদাহরণের তুলনায় উপরেরটি কিছুটা জটিল, বাশার পার্সিং-ক্রম এবং অদ্ভুততার উপর আরও বেশি নির্ভর করে। evalলাইন মোটামুটিভাবে নিম্নলিখিত ক্রমে অভ্যন্তরীণভাবে পার্স পেতে হবে (নোট নিম্নলিখিত বিবৃতি, pseudocode হয় না বাস্তব কোড শুধু দেখানোর জন্য কিভাবে বিবৃতি চূড়ান্ত ফলাফল উতরান থেকে অভ্যন্তরীণভাবে পদক্ষেপ বিভাজিত পেতে হবে প্রচেষ্টা করার জন্য)

 eval eval \$$keyA=\$$valA  # substitution of $keyA and $valA by interpreter
 eval eval \$keyB=\$valB    # convert '$' + name-strings to real vars by eval
 eval $keyB=$valB           # substitution of $keyB and $valB by interpreter
 eval that=amazing          # execute string literal 'that=amazing' by eval

যদি ধরে নেওয়া বিশ্লেষণের আদেশটি ব্যাখ্যা করে না যে কী পরিমাণ যথেষ্ট পরিমাণে alওয়াল করছে তা তৃতীয় উদাহরণটি পার্সিংকে আরও বিশদে বিশদ বিবরণ দিতে পারে যা চলছে তা স্পষ্ট করতে।



উদাহরণ 4:

বর্ণগুলি, যাদের নামগুলি স্ট্রিংয়ে অন্তর্ভুক্ত রয়েছে, সেগুলিতে স্ট্রিংয়ের মান রয়েছে কিনা তা আবিষ্কার করুন ।

a="User-provided"
b="Another user-provided optional value"
c=""

myvarname_a="a"
myvarname_b="b"
myvarname_c="c"

for varname in "myvarname_a" "myvarname_b" "myvarname_c"; do
    eval varval=\$$varname
    if [ -z "$varval" ]; then
        read -p "$varname? " $varname
    fi
done

প্রথম পুনরাবৃত্তিতে:

varname="myvarname_a"

বাশ যুক্তিটিকে পার্স করে eval, এবং evalআক্ষরিকভাবে এটি রানটাইমের সময় দেখায়:

eval varval=\$$myvarname_a

নিম্নলিখিত সিউডোকোড চিত্রিত করার চূড়ান্ত মানটিতে পৌঁছানোর জন্য কীভাবে ব্যাশ রিয়েল কোডের উপরের রেখাটিকে ব্যাখ্যা করে তা বোঝানোর চেষ্টা করে eval। (নিম্নলিখিত লাইনগুলি বর্ণনামূলক, সঠিক বাশ কোড নয়):

1. eval varval="\$" + "$varname"      # This substitution resolved in eval statement
2. .................. "$myvarname_a"  # $myvarname_a previously resolved by for-loop
3. .................. "a"             # ... to this value
4. eval "varval=$a"                   # This requires one more parsing step
5. eval varval="User-provided"        # Final result of parsing (eval executes this)

সমস্ত পার্সিং হয়ে গেলে, ফলাফলটি যা ঘটেছিল তা কার্যকর হয় এবং এর প্রভাব সুস্পষ্ট, এটি প্রমাণ করে যে evalনিজের সম্পর্কে বিশেষত রহস্যজনক কিছু নেই এবং জটিলতা তার যুক্তির বিশ্লেষণে রয়েছে।

varval="User-provided"

উপরের উদাহরণের বাকী কোডটি কেবল $ ভার্ভলে নির্ধারিত মানটি নাল কিনা তা পরীক্ষা করে দেখায় এবং যদি তাই হয় তবে ব্যবহারকারীকে একটি মান প্রদান করতে অনুরোধ জানায়।


3

আমি মূলত ইচ্ছাকৃতভাবে কখনই ওয়াল ব্যবহার করতে শিখি নি, কারণ বেশিরভাগ লোক প্লেগের মতো এটি থেকে দূরে থাকার পরামর্শ দেবে। তবে আমি সম্প্রতি একটি ব্যবহারের বিষয়টি আবিষ্কার করেছি যা এটির তাড়াতাড়ি স্বীকৃতি না দেওয়ার জন্য আমাকে ফেসপাম তৈরি করেছে।

যদি আপনার ক্রোন জব থাকে যা আপনি পরীক্ষার জন্য ইন্টারেক্টিভভাবে চালাতে চান তবে আপনি ফাইলের সামগ্রীগুলি বিড়ালের সাথে দেখতে পারেন এবং এটি চালানোর জন্য ক্রোন জবটি অনুলিপি করে আটকান। দুর্ভাগ্যক্রমে, এটিতে মাউস স্পর্শ করা জড়িত যা আমার বইয়ের একটি পাপ।

বলুন যে আপনার /etc/cron.d/repeatme এ সামগ্রীগুলি সহ ক্রোন জব রয়েছে:

*/10 * * * * root program arg1 arg2

আপনি এর সামনে সমস্ত আবর্জনা সহ স্ক্রিপ্ট হিসাবে এটি সম্পাদন করতে পারবেন না, তবে আমরা সমস্ত আবর্জনা থেকে মুক্তি পেতে, এটি একটি সাবশেলে মোড়ানো করতে এবং স্ট্রিংটি খোলাসা দিয়ে কার্যকর করতে পারি cut

eval $( cut -d ' ' -f 6- /etc/cron.d/repeatme)

কাট কমান্ড কেবল ফাঁকের ফাঁকে ফাঁকে ফাইলের 6th ষ্ঠ ক্ষেত্র প্রিন্ট করে। ইভাল তখন সেই আদেশটি কার্যকর করে।

আমি এখানে উদাহরণ হিসাবে একটি ক্রোন জব ব্যবহার করেছি, তবে ধারণাটি স্ট্যান্ডআউট থেকে পাঠ্য ফর্ম্যাট করা এবং তারপরে সেই পাঠ্যটি মূল্যায়ন করা।

এক্ষেত্রে ইওল ব্যবহার অনিরাপদ নয়, কারণ আমরা ঠিক জানি আমরা হাতের আগে যা মূল্যায়ন করব।


2

আমি সম্প্রতি evalআমার প্রয়োজন অনুসারে একাধিক ব্রেস প্রসারকে মূল্যায়ন করতে বাধ্য করতে ব্যবহার করেছি । বাশ বাম থেকে ডানে একাধিক ব্রেস প্রসারিত করে

xargs -I_ cat _/{11..15}/{8..5}.jpg

প্রসারিত হয়

xargs -I_ cat _/11/8.jpg _/11/7.jpg _/11/6.jpg _/11/5.jpg _/12/8.jpg _/12/7.jpg _/12/6.jpg _/12/5.jpg _/13/8.jpg _/13/7.jpg _/13/6.jpg _/13/5.jpg _/14/8.jpg _/14/7.jpg _/14/6.jpg _/14/5.jpg _/15/8.jpg _/15/7.jpg _/15/6.jpg _/15/5.jpg

তবে আমার প্রথম ধনুকের দ্বিতীয় ধনুর্বন্ধনী প্রসারণ প্রয়োজন

xargs -I_ cat _/11/8.jpg _/12/8.jpg _/13/8.jpg _/14/8.jpg _/15/8.jpg _/11/7.jpg _/12/7.jpg _/13/7.jpg _/14/7.jpg _/15/7.jpg _/11/6.jpg _/12/6.jpg _/13/6.jpg _/14/6.jpg _/15/6.jpg _/11/5.jpg _/12/5.jpg _/13/5.jpg _/14/5.jpg _/15/5.jpg

আমি যেটা করতে পেরেছি সেরা

xargs -I_ cat $(eval echo _/'{11..15}'/{8..5}.jpg)

এটি কাজ করে কারণ একক উদ্ধৃতি evalকমান্ড লাইনের বিশ্লেষণের সময় প্রথম ধনুর্বন্ধনী প্রসারণ থেকে রক্ষা করে , সেগুলি দ্বারা চালিত সাব-শেল দ্বারা প্রসারিত করে রেখে দেয় eval

নেস্টেড ব্রেস সম্প্রসারণের সাথে জড়িত কিছু ধূর্ত স্কিম থাকতে পারে যা এটি এক ধাপে ঘটতে দেয়, তবে যদি সেখানে থাকে তবে আমি এটি দেখতে পুরানো এবং বোকা।


1

আপনি সাধারণ ব্যবহার সম্পর্কে জিজ্ঞাসা করেছেন।

শেল স্ক্রিপ্টিং সম্পর্কে একটি সাধারণ অভিযোগ হ'ল আপনি (অভিযোগে) ফাংশনগুলির বাইরে মানগুলি পেতে রেফারেন্স দিয়ে পাস করতে পারবেন না।

তবে আসলে, "ইভাল" এর মাধ্যমে আপনি রেফারেন্স দিয়ে যেতে পারেন । কলি কলার দ্বারা মূল্যায়ন করার জন্য ভেরিয়েবল অ্যাসাইনমেন্টের একটি তালিকা ফেরত দিতে পারে। এটি রেফারেন্স দ্বারা পাস হয়েছে কারণ কলার ফলাফল পরিবর্তনশীল (গুলি) এর নাম (গুলি) নির্দিষ্ট করার অনুমতি দিতে পারে - নীচের উদাহরণটি দেখুন। ত্রুটির ফলাফলগুলি এরনো এবং এরস্টারের মতো স্ট্যান্ডার্ড নামগুলিতে ফিরে যেতে পারে।

এখানে ব্যাশে রেফারেন্স দিয়ে যাওয়ার উদাহরণ দেওয়া হয়েছে:

#!/bin/bash
isint()
{
    re='^[-]?[0-9]+$'
    [[ $1 =~ $re ]]
}

#args 1: name of result variable, 2: first addend, 3: second addend 
iadd()
{
    if isint ${2} && isint ${3} ; then
        echo "$1=$((${2}+${3}));errno=0"
        return 0
    else
        echo "errstr=\"Error: non-integer argument to iadd $*\" ; errno=329"
        return 1
    fi
}

var=1
echo "[1] var=$var"

eval $(iadd var A B)
if [[ $errno -ne 0 ]]; then
    echo "errstr=$errstr"
    echo "errno=$errno"
fi
echo "[2] var=$var (unchanged after error)"

eval $(iadd var $var 1)
if [[ $errno -ne 0 ]]; then
    echo "errstr=$errstr"
    echo "errno=$errno"
fi  
echo "[3] var=$var (successfully changed)"

আউটপুটটি দেখতে এটির মতো দেখাচ্ছে:

[1] var=1
errstr=Error: non-integer argument to iadd var A B
errno=329
[2] var=1 (unchanged after error)
[3] var=2 (successfully changed)

সেই পাঠ্য আউটপুটে প্রায় সীমাহীন ব্যান্ড প্রস্থ রয়েছে! একাধিক আউটপুট লাইন ব্যবহার করা হয় এবং আরও অনেক সম্ভাবনা রয়েছে: উদাহরণস্বরূপ, প্রথম লাইনটি পরিবর্তনশীল অ্যাসাইনমেন্টের জন্য ব্যবহৃত হতে পারে, দ্বিতীয়টি ধারাবাহিক 'চিন্তার ধারা' জন্য, তবে এটি এই পোস্টের আওতার বাইরে beyond


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

0

আমি "মৃত্যুর পূর্বে আরও একটি সময় আপনার অভিব্যক্তি মূল্যায়ন" উত্তর পছন্দ করি এবং অন্য একটি উদাহরণ দিয়ে স্পষ্ট করে বলতে চাই।

var="\"par1 par2\""
echo $var # prints nicely "par1 par2"

function cntpars() {
  echo "  > Count: $#"
  echo "  > Pars : $*"
  echo "  > par1 : $1"
  echo "  > par2 : $2"

  if [[ $# = 1 && $1 = "par1 par2" ]]; then
    echo "  > PASS"
  else
    echo "  > FAIL"
    return 1
  fi
}

# Option 1: Will Pass
echo "eval \"cntpars \$var\""
eval "cntpars $var"

# Option 2: Will Fail, with curious results
echo "cntpars \$var"
cntpars $var

বিকল্প 2 এর কৌতূহলের ফলাফলগুলি হ'ল আমরা নীচে 2 পরামিতিগুলি পার করেছি:

  • প্রথম প্যারামিটার: "value
  • দ্বিতীয় পরামিতি: content"

কিভাবে এটি স্বজ্ঞাত পাল্টা জন্য? অতিরিক্ত evalএটি ঠিক করবে।

Https://stackoverflow.com/a/40646371/744133 থেকে অভিযোজিত


0

প্রশ্নে:

who | grep $(tty | sed s:/dev/::)

আউটপুট ত্রুটি দাবি করে যে ফাইলগুলির একটি এবং টিটিই নেই। আমি এটি বুঝতে পেরেছিলাম যে গ্রেটি কার্যকর করার আগে টিটিটির ব্যাখ্যা করা হচ্ছে না, তবে পরিবর্তে বাশ টিটিটি গ্রেপকে পরামিতি হিসাবে পাঠিয়েছে, যা এটি ফাইলের নাম হিসাবে ব্যাখ্যা করে।

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

আমি গ্রেপ দিয়ে সুনির্দিষ্ট হয়েছি এবং পাইপ ব্যবহার না করে ফাইলটিকে পরামিতি হিসাবে নির্দিষ্ট করেছি। আমি কমান্ড থেকে ফাইল হিসাবে আউটপুট পাস করে বেস কমান্ডটিও সরলীকরণ করেছি, যাতে i / o পাইপিংয়ের ব্যবস্থা না হয়:

grep $(tty | sed s:/dev/::) <(who)

ভাল কাজ করে.

who | grep $(echo pts/3)

সত্যই পছন্দসই নয়, তবে নেস্টেড পাইপকে সরিয়ে দেয় এবং ভালভাবে কাজ করে।

উপসংহারে, বাশ নেস্টেড পাইপিং পছন্দ করছে বলে মনে হয় না। এটি বোঝার জন্য গুরুত্বপূর্ণ যে বাশ কোনও পুনরাবৃত্ত পদ্ধতিতে লিখিত নতুন তরঙ্গ প্রোগ্রাম নয়। পরিবর্তে, বাশ পুরানো 1,2,3 প্রোগ্রাম, যা বৈশিষ্ট্যগুলি যুক্ত করা হয়েছে। পশ্চাদপদ সামঞ্জস্যতা নিশ্চিত করার উদ্দেশ্যে, ব্যাখ্যাটির প্রাথমিক পদ্ধতি কখনও কখনও সংশোধন করা হয়নি। বাশকে যদি প্রথম ম্যাচের বন্ধনীতে পুনরায় লেখা হয় তবে কতটি ব্যাগ প্রোগ্রামে কতগুলি বাগ প্রবর্তিত হবে? অনেক প্রোগ্রামার ক্রিপ্টিক হতে পছন্দ করেন।

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