বাশ মধ্যে "eval" কমান্ড কি?


176

আপনি evalকমান্ড দিয়ে কি করতে পারেন ? কেন এটি দরকারী? বাশে এটি কোনও ধরণের বিল্ট-ইন ফাংশন? manএটির জন্য কোনও পৃষ্ঠা নেই ..


28
কমান্ডtype command কী টাইপ তা শিখতে ব্যবহার করুন । ( type eval
সেক্ষেত্রে

9
"এভাল হ'ল একটি শেল নির্মিত"
নুনো রাফায়েল ফিগুয়েরিডো

3
help evalআপনার শেল থেকে "ম্যান" পৃষ্ঠা পেতে
এম ধনী

ইভাল বাশ-বিল্টিন এবং ব্যাশের ম্যান পৃষ্ঠাতে নথিভুক্ত। সুতরাং কেবল "ম্যান বাশ" টাইপ করুন এবং এভাল জন্য উপযুক্ত বিভাগটি অনুসন্ধান করুন। এটি অন্যান্য ব্যাশ-বিল্টিনগুলির জন্যও প্রযোজ্য।
ডার্ক থানহুউসার

উত্তর:


132

evalপসিক্স এর অংশ। এটি একটি ইন্টারফেস যা শেল্ট অন্তর্নির্মিত হতে পারে।

এটি "পসিক্স প্রোগ্রামার ম্যানুয়াল" তে বর্ণিত হয়েছে: http://www.unix.com/man-page/posix/1posix/eval/

eval - construct command by concatenating arguments

এটি একটি আর্গুমেন্ট নেবে এবং এর একটি কমান্ড তৈরি করবে, যা শেল দ্বারা কার্যকর করা হবে। এটি ম্যানপেজের উদাহরণ:

1) foo=10 x=foo
2) y='$'$x
3) echo $y
4) $foo
5) eval y='$'$x
6) echo $y
7) 10
  1. প্রথম লাইন আপনি সংজ্ঞায়িত $fooমান '10'এবং $xমান 'foo'
  2. এখন সংজ্ঞায়িত করুন $y, যা স্ট্রিং নিয়ে গঠিত '$foo'। ডলারের সাইনটি দিয়ে পালাতে হবে '$'
  3. ফলাফল পরীক্ষা করতে echo $y,।
  4. ফলাফল স্ট্রিং হবে '$foo'
  5. এখন আমরা এই নিয়োগটি পুনরাবৃত্তি eval। এটি প্রথমে $xস্ট্রিংয়ের মূল্যায়ন করবে 'foo'। এখন আমরা বিবৃতি y=$fooযা মূল্যায়ন করা হবে y=10
  6. ফলাফল echo $yএখন মান '10'

এটি অনেকগুলি ভাষায় একটি সাধারণ কাজ, যেমন পার্ল এবং জাভাস্ক্রিপ্ট। আরও উদাহরণের জন্য পার্লডোক ইওল দেখুন: http://perldoc.perl.org/function/eval.html


4
শেল পরিভাষায়, evalএকটি অন্তর্নির্মিত, কোনও ফাংশন নয়। অনুশীলনে, বিল্ট-ইনগুলি অনেকগুলি ফাংশনগুলির মতো আচরণ করে যার একটি ইন-ল্যাঙ্গুয়েজ সংজ্ঞা নেই, তবে বেশ নয় (যদি আপনি কোনও ফাংশন সংজ্ঞায়িত করার জন্য যথেষ্ট মোচড় হয়ে থাকেন তবে তা স্পষ্ট হয়ে যায় eval)।
গিলস

thx, স্থির হয়েছে :-)
ইকক্স

4
ইভাল এবং ব্যাকটিক্স-এর মধ্যে পার্থক্য কী?
জনিটেক্স

5
ব্যাকটিকগুলি অন্য একটি সম্পূর্ণ শেল কার্যকর করার জন্য শর্টহ্যান্ড, এর অর্থ আপনার স্ক্রিপ্টের মধ্যে অন্য চাইল্ড বাশ / শ প্রক্রিয়া চলবে।
অ্যারন আর।

প্রতিধ্বনি $ y (পর্যায় 3) কেন foo (10) এর পরিবর্তে ফি (10) এনেছে? (অর্থাত্ স্ট্রিংয়ের পরিবর্তে কেবল ফু এর মান f + ফু এর মান)?
জনডোইয়া

60

হ্যাঁ, evalএটি বাশ অভ্যন্তরীণ কমান্ড তাই এটি bashম্যান পৃষ্ঠাতে বর্ণিত ।

eval [arg ...]
    The  args  are read and concatenated together into a single com-
    mand.  This command is then read and executed by the shell,  and
    its  exit status is returned as the value of eval.  If there are
    no args, or only null arguments, eval returns 0.

সাধারণত এটি একটি কমান্ড সাবস্টিটিউশনের সাথে সংমিশ্রণে ব্যবহৃত হয় । স্পষ্টতই eval, শেল একটি কমান্ড প্রতিস্থাপনের ফলাফলটি কার্যকর করার চেষ্টা করে , এটির মূল্যায়ন না করে।

বলুন যে আপনি এর সমতুল্য কোড করতে চান VAR=value; echo $VAR। শেল কীভাবে এই লেখাগুলি পরিচালনা করে তার মধ্যে পার্থক্যটি নোট করুন echo VAR=value:

  1. andcoz@...:~> $( echo VAR=value )
    bash: VAR=value: command not found
    andcoz@...:~> echo $VAR
    <empty line>
    

    শেলটি কার্যকর করতে echoএবং VAR=valueদুটি পৃথক কমান্ড হিসাবে চেষ্টা করে। এটি দ্বিতীয় স্ট্রিং সম্পর্কে একটি ত্রুটি নিক্ষেপ করে। অ্যাসাইনমেন্টটি অকার্যকর থাকে।

  2. andcoz@...:~> eval $( echo VAR=value )
    andcoz@...:~> echo $VAR
    value
    
    শেল মার্জ (যোগসূত্র) দুটি স্ট্রিং echoএবং VAR=valueউপযুক্ত নিয়ম অনুযায়ী এই একক ইউনিট parses এবং এটি সঞ্চালন করে।

সর্বশেষ কিন্তু অন্তত নয়, evalএকটি খুব বিপজ্জনক আদেশ হতে পারে। evalসুরক্ষা সমস্যা এড়াতে কোনও কমান্ডের যে কোনও ইনপুট অবশ্যই সাবধানে পরীক্ষা করা উচিত।


18

evalকোনও ম্যান পেজ নেই কারণ এটি পৃথক বাহ্যিক কমান্ড নয়, বরং শেলটি অন্তর্নির্মিত, যার অর্থ একটি অভ্যন্তরের অভ্যন্তরীণ এবং কেবল শেল ( bash) দ্বারা পরিচিত । bashম্যান পৃষ্ঠার প্রাসঙ্গিক অংশটি বলেছেন:

eval [arg ...]
    The args are read and concatenated together into a single command.  
    This command is then  read  and executed by the shell, and its exit 
    status is returned as the value of eval.  If there are no args, or only 
    null arguments, eval returns 0

এছাড়াও, আউটপুট যদি help evalহয়:

eval: eval [arg ...]
    Execute arguments as a shell command.

    Combine ARGs into a single string, use the result as input to the shell,
    and execute the resulting commands.

    Exit Status:
    Returns exit status of command or success if command is null.

evalএকটি শক্তিশালী কমান্ড এবং যদি আপনি এটি ব্যবহার করতে চান তবে আপনার এটির সাথে সম্ভাব্য সুরক্ষা ঝুঁকির মুখোমুখি হওয়া উচিত careful


16

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

আপনার স্ক্রিপ্টে যদি আপনি কোনও কমান্ডকে ভেরিয়েবলের মধ্যে সংজ্ঞা দিয়ে থাকেন এবং পরে আপনি সেই কমান্ডটি ব্যবহার করতে চান তবে আপনার উচিত 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 >

3
আপনার উদাহরণের 4 লাইনে থাকা মন্তব্যটি ভুল: এটি হওয়া উচিত "উপরের কমান্ডটি কাজ করে না কারণ বাশ একটি কমান্ড সন্ধান করার চেষ্টা করেছিল ls | more। অন্য কথায়: একক কমান্ডের নামটি ফাঁকা এবং পাইপ চিহ্ন সহ নয়টি অক্ষর নিয়ে গঠিত ।
সিএফআই

তিনি ঠিক যে আচরণ করেছিলেন সেটাই আমি পেয়েছি। বাশ - রূপান্তর == জিএনইউ ব্যাশ, সংস্করণ 3.2.57 (1) -রিলিজ (x86_64-আপেল-ডারউইন 18)
আলেকজান্ডার বার্ড

10

Alভাল কি?

ইভাল একটি শেল কমান্ড যা সাধারণত বিল্টিন হিসাবে প্রয়োগ করা হয়।

পসিক্সে এটি "2.14 এর অংশ হিসাবে তালিকাভুক্ত করা হয়েছে । বিশেষ বিল্ট-ইন ইউটিলিটিস" এন্ট্রি "ইভাল" এ
বিল্টিন মানে কী:

"বিল্ট-ইন" শব্দটি বোঝায় যে শেলটি সরাসরি ইউটিলিটি চালাতে পারে এবং এটির জন্য অনুসন্ধান করার দরকার নেই।

এটার কাজ কি?

সহজ কথায়: একটি ইনপুট লাইন দু'বার পার্স করার জন্য তোলে ।

কীভাবে তা করে?

শেলের একটি ধাপের ক্রম রয়েছে যা এটি একটি লাইন "প্রক্রিয়া" করতে অনুসরণ করে। আপনি এই চিত্রটি দেখে বুঝতে পেরেছিলেন যে বামদিকে, ওয়ালটি একমাত্র লাইন যা পিছনে 1 ষ্ঠ ধাপে ফিরে যায়। থেকে POSIX বিবরণ :

2.1 শেল পরিচিতি

  1. শেলটি তার ইনপুটটি পড়ে ...
  2. শেলটি ইনপুটটিকে টোকেনে বিভক্ত করে: শব্দ এবং অপারেটর
  3. শেলটি ইনপুটটিকে সাধারণ এবং যৌগিক কমান্ডগুলিতে পার্স করে।
  4. শেলটি বিভিন্ন বিস্তৃতকরণ (পৃথকভাবে) সম্পাদন করে ...
  5. শেলটি পুনঃনির্দেশ সম্পাদন করে এবং প্যারামিটার তালিকা থেকে পুনঃনির্দেশ অপারেটর এবং তাদের অপারেশনগুলি সরিয়ে দেয়।
  6. শেলটি একটি ফাংশন, অন্তর্নির্মিত, এক্সিকিউটেবল ফাইল, বা স্ক্রিপ্ট কার্যকর করে ...
  7. শেলটি allyচ্ছিকভাবে কমান্ডটি শেষ হওয়ার জন্য অপেক্ষা করে এবং প্রস্থান স্থিতি সংগ্রহ করে।

Step ধাপে একটি অন্তর্নির্মিত কার্যকর করা হবে।
Step ধাপে ইওল প্রক্রিয়াযুক্ত লাইনটি ধাপে পুনরায় পাঠিয়ে দেয় 1.
এটি একমাত্র শর্ত যার অধীনে সম্পাদন ক্রমটি ফিরে যায়।

এই কারণেই আমি বলছি: ইভাল সহ একটি ইনপুট লাইন দু'বার পার্স করা হয়

দুবার পার্সিংয়ের প্রভাব।

প্রথম.

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

উদ্ধৃতি অপসারণ সর্বদা শেষ করা হবে।

সুতরাং, সর্বদা, উদ্ধৃতি সরানোর একটি স্তর রয়েছে।

দ্বিতীয়ত।

এই প্রথম প্রভাবের ফলস্বরূপ, লাইনের অতিরিক্ত / বিভিন্ন অংশ শেল পার্সিং এবং অন্যান্য সমস্ত পদক্ষেপের সংস্পর্শে আসে।

উদাহরণ।

অপ্রত্যক্ষ্যতার।

যা পরোক্ষ বিস্তৃতি কার্যকর করতে দেয়:

a=b b=c    ;    eval echo \$$a            ### shall produce "c"

কেন? কারণ প্রথম লুপে প্রথমটি $উদ্ধৃত হয়।
এই হিসাবে, এটি শেল দ্বারা বিস্তারের জন্য উপেক্ষা করা হয়। নামের সাথে
পরবর্তীটি $"বি" উত্পাদন করতে প্রসারিত হয়।
তারপরে, প্রথম $স্তরটিকে উদ্ধৃত করে একটি স্তরের উদ্ধৃতি সরানো হবে ।
প্রথম লুপের সমাপ্তি।

তারপরে, দ্বিতীয় লুপের উপরে স্ট্রিংটি $bশেল দ্বারা পড়ে।
তারপরে "সি" তে প্রসারিত হয়ে
যুক্তি হিসাবে দেওয়া হয়েছে echo

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

$ a=b b=c
$ eval echo \$$a;
c

কী হচ্ছে তা "দেখুন" তে প্রতিধ্বনি দ্বারা প্রতিস্থাপন করুন:

$ echo echo \$$a
echo $b

এটির সাথে একটি লাইনের সমস্ত "অংশ" দেখানোও সম্ভব:

$ printf '<%s> ' echo \$$a
<echo> <$b>

যা এই উদাহরণে কেবল একটি প্রতিধ্বনি এবং একটি পরিবর্তনশীল তবে আরও জটিল কেসগুলি মূল্যায়নে সহায়তা করতে এটি মনে রাখবেন।

একটি সংশোধন।

এটি অবশ্যই বলা উচিত: উপরের কোডটিতে একটি ভুল রয়েছে, আপনি এটি দেখতে পারেন ?.
সহজ: এখানে কিছু উদ্ধৃতি নেই।

কিভাবে? আপনি জিজ্ঞাসা করতে পারেন। সরল, আসুন ভেরিয়েবলগুলি পরিবর্তন করুন (কোড নয়):

$ a=b b="hi     jk"
$ eval echo \$$a
hi jk

নিখোঁজ স্থানগুলি দেখুন?
এর কারণ ভিতরে মানটি $bশেল দ্বারা বিভক্ত হয়েছিল।

যদি এটি আপনাকে বোঝায় না, তবে চেষ্টা করুন:

$ a=b b="hi  *  jk"
$ eval echo \$$a              ### warning this will expand to the list  
                              ### of all files in the present directory.

কেন?

হারিয়ে যাওয়া উক্তি। এটি সঠিকভাবে কাজ করতে (অভ্যন্তরীণ "$a"এবং বাহ্যিক \"উদ্ধৃতি যুক্ত করুন)।
এটি চেষ্টা করুন (পুরোপুরি নিরাপদ):

$ a=b b="hi      *       jk"
$ eval echo \" \$"$a" \"
hi      *       jk

ম্যানুয়াল সম্পর্কে:

এর জন্য কোনও ম্যান পেজ নেই ..

না, এর জন্য স্বতন্ত্র ম্যান পৃষ্ঠা নেই। সহ ম্যানুয়াল অনুসন্ধান man -f evalবা এমনকি apropos evalকোনও এন্ট্রি দেখায় না।

এটি ভিতরে অন্তর্ভুক্ত করা হয় man bash। যেমন অন্তর্নির্মিত হয়।
"শেল বিল্টিন কম্যান্ডস" এবং তারপরে "ইভাল" এর জন্য অনুসন্ধান করুন।

সহায়তা পাওয়ার একটি সহজ উপায় হ'ল: ব্যাশ-এ, আপনি help evalঅন্তর্নির্মিতদের জন্য সহায়তা দেখতে পারেন।

কেন alশালকে মন্দ বলা হয়?

কারণ এটি কোডকে পাঠ্যের সাথে গতিশীলভাবে বাধ্যতামূলক করে।

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

বা এমনকি সহজ, আপনি যাকে এক বা একাধিক যুক্তির মান সংজ্ঞায়িত করেছেন তা সহকারে বলছেন:

কমন, এখানে বসে কোনও কমান্ড লাইন টাইপ করুন, আমি এটিকে আমার শক্তি দিয়ে কার্যকর করব।

এটা কি বিপজ্জনক? এটি সবার জন্য পরিষ্কার হওয়া উচিত।

Eval জন্য নিরাপত্তা নিয়ম হওয়া উচিত:
শুধু ভেরিয়েবল যা উপর Eval চালানো আপনি এটা মান দিয়েছেন।

এখানে আরও বিস্তারিত পড়ুন ।


10

evalসবচেয়ে ব্যাখ্যা ভাষা (একটি বৈশিষ্ট্য TCL, python, ruby...) না শুধুমাত্র শাঁস। এটি গতিশীলভাবে কোড মূল্যায়নের জন্য ব্যবহৃত হয়।

শেলগুলিতে এটি শেল বিল্টিন কমান্ড হিসাবে প্রয়োগ করা হয়।

মূলত, evalযুক্তি হিসাবে একটি স্ট্রিং নেয় এবং এতে কোডটি মূল্যায়ন / ব্যাখ্যা করে। শেলগুলিতে, evalএকাধিক যুক্তি নিতে evalপারে তবে মূল্যায়নের জন্য স্ট্রিং গঠনের জন্য কেবল তাদের সাথে সম্মতি জানায়।

এটি খুব শক্তিশালী কারণ আপনি গতিশীলভাবে কোড তৈরি করতে এবং এটি চালাতে পারেন, এমন কিছু যা আপনি সি এর মতো সংকলিত ভাষায় করতে পারবেন না something

ভালো লেগেছে:

varname=$1 varvalue=$2
eval "$varname=\$varvalue" # evaluate a string like "foo=$varvalue"
                           # which in Bourne-like shell language
                           # is a variable assignment.

তবে এটিও বিপজ্জনক evalকারণ শেল কোড হিসাবে এটি ব্যাখ্যা করার কারণেই যা পাস করা হয়েছে তার গতিশীল (বাহ্যিকভাবে সরবরাহ করা) অংশগুলি স্যানিটাইজ করা গুরুত্বপূর্ণ ।

উদাহরণস্বরূপ, যদি আপনার উপরে $1হয় evil-command; var, evalশেষ-আপ হবে মূল্যায়নের evil-command; var=$varvalueশেল কোড এবং তারপর যে চালানো evil-command

দুষ্টতা evalপ্রায়শই অত্যুক্তি করা হয়।

ঠিক আছে, এটি বিপজ্জনক তবে কমপক্ষে আমরা জানি এটি বিপজ্জনক।

যদি মত (শেল উপর নির্ভর করে), sanitized অন্য কমান্ড অনেক আর্গুমেন্ট মধ্যে শেল কোড মূল্যায়ন করবে [ওরফে test, export, printf, গনুহ sed, awk, এবং অবশ্যই sh/ bash/ perlসমস্ত দোভাষী ...

উদাহরণ (এখানে unameহিসাবে হিসাবে evil-commandএবং $aবহিরাগতভাবে সরবরাহিত অ সঞ্জনিত ডেটা হিসাবে ব্যবহার করে):

$ a='$(uname>&2)' sh -c 'eval "echo $a"'
Linux

$ a='x[0$(uname>&2)]' mksh -c 'export "$a=$b"'
Linux
$ a='x[0$(uname>&2)]' ksh93 -c 'printf "%d\n" "$a"'
Linux
0
$ a='x[0$(uname>&2)]' ksh93 -c '[ "$a" -gt 0 ]'
Linux
$ a=$'bar/g;e uname>&2\n;s//'; echo foo | sed "s/foo/$a/g"
Linux
bar
$ a='";system("uname");"'; awk "BEGIN{print \"$a\"}"

Linux
$ a=';uname'; sh -c "echo $a"

Linux

sed, export... কমান্ড বেশী বিপজ্জনক বিবেচিত হওয়ার কারণে যখন এটা সুস্পষ্ট eval "$var"বিষয়বস্তুর কারণ হবে $varশেল কোড হিসেবে মূল্যায়ন করা, এটা না, তাই সুস্পষ্ট সাথে sed "s/foo/$var/"বা export "$var=value"বা [ "$var" -gt 0 ]। ড্যানগ্রোসিটি একই, তবে এটি অন্যান্য কমান্ডগুলিতে গোপন রয়েছে।


@ বাইনারিজেব্রা, sedযেমন evalএকটি ভেরিয়েবলের মধ্যে থাকা একটি স্ট্রিং পাস হচ্ছে এবং উভয়ের জন্যই, সেই স্ট্রিংয়ের বিষয়বস্তুটি শেল কোড হিসাবে মূল্যায়ন করা শেষ হয়, তাই আমি যা বলছি তাই sedবিপজ্জনক evalsedএকটি স্ট্রিং দিয়ে পাস করা হচ্ছে uname(অমান্য এখনও অবধি কার্যকর করা হয়নি) এবং এর আহ্বানের মাধ্যমে sedআনমে কমান্ড কার্যকর করা শেষ হয়। ইওল এর মত ইন sed 's/foo/$a/g', আপনি এতে নিরবচ্ছিন্ন ডেটা দিচ্ছেন না sed, আমরা এখানে এখানেই বলছি না।
স্টাফেন চেজেলাস

2

এই উদাহরণটি কিছুটা আলোকপাত করতে পারে:

#!/bin/bash
VAR1=25
VAR2='$VAR1'
VAR3='$VAR2'
echo "$VAR3"
eval echo "$VAR3"
eval eval echo "$VAR3"

উপরের স্ক্রিপ্টটির আউটপুট:

$VAR2
$VAR1
25

আপনার অবদানের জন্য ধন্যবাদ, তবে তারা যেমন আনন্দদায়ক, আমরা ব্যবহারের (কিছুটা আলাদা) উদাহরণগুলির একটি তালিকা সংকলনে সত্যই আগ্রহী নই eval। আপনি কি বিশ্বাস করেন যে এর কার্যকারিতাটির কিছু মৌলিক, সমালোচনামূলক দিক evalবিদ্যমান উত্তরগুলিতে আবৃত নয়? যদি তা হয় তবে তা ব্যাখ্যা করুন এবং আপনার ব্যাখ্যাটি উদাহরণের জন্য উদাহরণটি ব্যবহার করুন। মন্তব্যে প্রতিক্রিয়া জানাতে দয়া করে;  আপনার উত্তরটি আরও পরিষ্কার এবং আরও পরিপূর্ণ করতে সম্পাদনা করুন।
স্কট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.