আপডেট: কিছু লোক বলছেন একজনের উচিত - ওভার-ওভার ব্যবহার করা উচিত। আমি একমত নই আমি মনে করি যখন দুর্নীতিগ্রস্ত ইনপুটটি দেওয়া যেতে পারে তখন ঝুঁকি দেখা দেয় eval
। তবে এমন অনেকগুলি সাধারণ পরিস্থিতি রয়েছে যেখানে এটি ঝুঁকিপূর্ণ নয়, এবং সুতরাং যে কোনও ক্ষেত্রে ইওলকে কীভাবে ব্যবহার করতে হয় তা জেনে রাখা মূল্যবান। এই স্ট্যাকওভারফ্লো উত্তরটি বিকাশের ঝুঁকি এবং বিবর্তনের বিকল্পগুলি ব্যাখ্যা করে। অবশেষে এটি কখন / কখন ইওল ব্যবহার করা নিরাপদ এবং দক্ষ কিনা তা নির্ধারণ করা ব্যবহারকারীর উপর নির্ভর করে।
বাশ eval
বিবৃতি আপনাকে আপনার বাশ স্ক্রিপ্ট দ্বারা গণনা করা বা অর্জিত কোডের লাইনগুলি সম্পাদন করতে দেয়।
সম্ভবত সবচেয়ে সহজ উদাহরণটি হ'ল বাশ প্রোগ্রাম যা একটি টেক্সট ফাইল হিসাবে অন্য একটি বাশ স্ক্রিপ্ট খুলবে, পাঠ্যের প্রতিটি লাইন পড়বে এবং eval
সেগুলি কার্যকর করার জন্য ব্যবহার করবে। এটি মূলত বাশ source
স্টেটমেন্টের মতোই আচরণ , যা আমদানি করা স্ক্রিপ্টের সামগ্রীতে কোনও ধরণের রূপান্তর (যেমন ফিল্টারিং বা প্রতিস্থাপন) সম্পাদন করা প্রয়োজন না হলে এটিই ব্যবহার করবে।
আমার খুব কমই প্রয়োজন হয়েছিল eval
তবে আমি ভেরিয়েবলগুলি পড়তে বা লিখতে দরকারী বলে মনে করি যাদের নামগুলি অন্যান্য ভেরিয়েবলগুলিতে নির্ধারিত স্ট্রিংয়ে অন্তর্ভুক্ত ছিল। উদাহরণস্বরূপ, ভেরিয়েবলগুলির সেটগুলিতে ক্রিয়া সম্পাদন করা, কোডের পদচিহ্নগুলি ছোট রাখার সময় এবং অতিরিক্ত কাজকে এড়াতে।
eval
ধারণাগতভাবে সহজ। তবে, বাশ ভাষার কঠোর বাক্য গঠন এবং ব্যাশ ইন্টারপ্রেটারের পার্সিং ক্রমটি সংজ্ঞায়িত হতে পারে এবং eval
ক্রিপ্টিক এবং ব্যবহার করতে বা বুঝতে অসুবিধে হয়। এখানে প্রয়োজনীয়:
আর্গুমেন্টটি পাস করা eval
একটি স্ট্রিং এক্সপ্রেশন যা রানটাইম সময়ে গণনা করা হয়। আপনার স্ক্রিপ্টে কোডের eval
একটি আসল লাইন হিসাবে এর যুক্তির চূড়ান্ত বিশ্লেষণের ফলাফল কার্যকর করবে ।
সিনট্যাক্স এবং পার্সিং অর্ডার কঠোর। ফলাফলটি যদি আপনার স্ক্রিপ্টের স্কোপ অনুযায়ী ব্যাশ কোডের একটি কার্যকরযোগ্য লাইন না হয় তবে প্রোগ্রামটি eval
বিবৃতিতে ক্র্যাশ করবে কারণ এটি আবর্জনা চালানোর চেষ্টা করে।
পরীক্ষা করার সময় আপনি 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"
উপরের উদাহরণের বাকী কোডটি কেবল $ ভার্ভলে নির্ধারিত মানটি নাল কিনা তা পরীক্ষা করে দেখায় এবং যদি তাই হয় তবে ব্যবহারকারীকে একটি মান প্রদান করতে অনুরোধ জানায়।
$($n)
চালায়$n
। এটি কমান্ডটি চালানোর চেষ্টা1
করে যা বিদ্যমান নেই।