"#! / Usr / bin / env বাশ" এবং "#! / Usr / বিন / বাশ" এর মধ্যে পার্থক্য কী?


371

বাশ স্ক্রিপ্টের শিরোনামে, এই দুটি বিবৃতিগুলির মধ্যে পার্থক্য কী:

  1. #!/usr/bin/env bash

  2. #!/usr/bin/bash

আমি যখন env ম্যান পৃষ্ঠার সাথে পরামর্শ করেছি , আমি এই সংজ্ঞাটি পেয়েছি:

 env - run a program in a modified environment

এর মানে কী?



6
"প্রোগ্রামিং বা সফ্টওয়্যার বিকাশের সাথে সম্পর্কিত" এই প্রশ্নটি কেন বন্ধ রয়েছে তা আমাকে কে বলতে পারে?
তারশাল্লাহ

1
আমি সম্মত এটি প্রসঙ্গ-বহির্ভূত নয়, কিন্তু এটা সম্ভবত যেমন বেশ কিছু প্রশ্ন সদৃশ যেটির এই এক
কিথ থম্পসন

16
এই প্রশ্নটি অফ-টপিক হিসাবে চিহ্নিত করা উচিত নয়। এটিকে "অন টপিক" হিসাবে চিহ্নিত করতে কেবল মাত্র 3000 এর উপরে স্কোরের জন্য 5 জন লোক প্রয়োজন এবং এটি আবার খোলা যেতে পারে। এটি একটি প্রশ্ন - বিশেষত প্রোগ্রামিং সম্পর্কে।
দানিজেল-জেমস ডাব্লু

3
আমি বিষ্মিত. লিনাক্স ডকুমেন্টেশন টাউটোলজিস সহ ছড়িয়ে পড়েছে তা শুনে হতবাক। xkcd.com/703 git-man-page-generator.lokaltog.net
allyourcode

উত্তর:


323

কমান্ড মাধ্যমে চলমান /usr/bin/envজন্য যাই হোক না কেন প্রোগ্রামের ডিফল্ট সংস্করণ আপনার বর্তমান রয়েছে খুঁজছেন সুবিধা রয়েছে env ironment।

এই পদ্ধতিতে, আপনাকে এটির জন্য সিস্টেমে নির্দিষ্ট স্থানে সন্ধান করতে হবে না, কারণ এই পাথগুলি বিভিন্ন সিস্টেমে বিভিন্ন স্থানে থাকতে পারে। যতক্ষণ না এটি আপনার পথে রয়েছে ততক্ষণ এটি এটি খুঁজে পাবে।

একটি খারাপ দিক হ'ল আপনি /usr/bin/env awk -fলিনাক্সকে সমর্থন করতে চাইলে আপনি একাধিক যুক্তি (যেমন আপনি লিখতে অক্ষম হবেন ) পাস করতে পারবেন না , কারণ লাইনটি কীভাবে ব্যাখ্যা করতে হবে সে সম্পর্কে অস্পষ্ট এবং লিনাক্স প্রথমটির পরে সমস্ত কিছু ব্যাখ্যা করে একক যুক্তি বোঝাতে স্থান। আপনি /usr/bin/env -Sএটি envপেতে কিছু সংস্করণে ব্যবহার করতে পারেন তবে স্ক্রিপ্টটি আরও কম পোর্টেবল হয়ে উঠবে এবং মোটামুটি সাম্প্রতিক সিস্টেমে (যেমন উদাবু 16.04 পরে যদি না হয় তবে) ভেঙে যায়।

আরেকটি নেতিবাচকতা হ'ল যেহেতু আপনি একটি সুস্পষ্ট সম্পাদনযোগ্যকে কল করছেন না, তাই এটি ভুলগুলির সম্ভাবনা পেয়েছে, এবং মাল্টুউজার সিস্টেমের সুরক্ষা সমস্যাগুলিতে (যদি কেউ bashআপনার পথে তাদের এক্সিকিউটেবল ডেকে আনতে সক্ষম হয় , উদাহরণস্বরূপ)।

#!/usr/bin/env bash #lends you some flexibility on different systems
#!/usr/bin/bash     #gives you explicit control on a given system of what executable is called

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


22
আর একটি অপূর্ণতা হ'ল আপনি দোভাষীর কাছে একটি অতিরিক্ত যুক্তি পাস করতে পারবেন না।
কিথ থম্পসন

1
@ কিথথম্পসন: ভুল তথ্য .. আপনি / usr / bin / env ব্যবহার করে অন্তর্নিহিত দোভাষীর কাছে বিকল্পগুলি দিতে পারেন!
গৌরব আগরওয়াল

4
@ গৌরব আগরওয়াল: আমার সিস্টেমে নেই। শুধু এই একক লাইন ধারণকারী একটি স্ক্রিপ্ট: #!/usr/bin/env echo Helloঅভিযোগ: /usr/bin/env: echo Hello: No such file or directory। স্পষ্টতই এটি echo Helloএকক যুক্তি হিসাবে আচরণ করে /usr/bin/env
কিথ থম্পসন

1
@ অ্যান্ড্রেলাস্লো: envকমান্ডটি অবশ্যই কমান্ডে যুক্তিগুলি সরবরাহ করার অনুমতি দেয়। ইস্যুটি #!লাইনের শব্দার্থক এবং এটি কার্নেলের উপর নির্ভর করে। সাম্প্রতিক লিনাক্স কার্নেলগুলি পছন্দ মতো জিনিসগুলিকে অনুমতি দেয় #!/usr/bin/env command argsতবে পুরানো লিনাক্স কার্নেল এবং অন্যান্য সিস্টেমগুলি তা দেয় না।
কিথ থম্পসন

1
কোড ব্লকে ব্যাকটিক্স কেন আছে? তাদের কি সরানো উচিত নয়?
বেনিয়ামিন ডাব্লু।

63

ব্যবহারটি #!/usr/bin/env NAMENAME এর প্রথম ম্যাচের জন্য শেল অনুসন্ধানকে $ PATH পরিবেশে পরিবর্তনশীল করে তোলে। আপনি যদি পরম পথ সম্পর্কে সচেতন না হন বা এটি অনুসন্ধান করতে না চান তবে এটি কার্যকর হতে পারে।


9
কমপক্ষে আপনাকে জানতে হবে এনভিটি কোথায় রয়েছে :)।
ri দেব্রিম্বারিস

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

13

/usr/bin/bash/Env কমান্ড ব্যবহার করে দোভাষীকে স্পষ্টভাবে সংজ্ঞায়িত করার পরিবর্তে , অনুবাদককে যেখানে অনুসন্ধান করা হয়েছিল সেখানেই এটি খুঁজে পাওয়া যায় এবং সেখানে এটি প্রথম পাওয়া যায়। এতে উভয়ই উত্সাহ এবং ডাউনসাইড রয়েছে


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

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

10

শেল স্ক্রিপ্ট দিয়ে শুরু এমন #!/bin/bash, তারা সবসময় সঙ্গে চালানো হবে bashথেকে /bin। যদি তারা কিন্তু দিয়ে শুরু #!/usr/bin/env bash, তারা অনুসন্ধান করবে bashমধ্যে$PATH এবং তারপর প্রথম এক তারা জানতে পারেন দিয়ে শুরু।

কেন এটি দরকারী হবে? ধরুন আপনি bashস্ক্রিপ্টগুলি চালাতে চান , এর জন্য বাশ 4.x বা আরও নতুন প্রয়োজন, তবুও আপনার সিস্টেমে কেবল আছেbash ৩.x ইনস্টল করা আছে এবং বর্তমানে আপনার ডিস্ট্রিবিউশনটি নতুন সংস্করণ সরবরাহ করে না বা আপনি কোনও প্রশাসক নন এবং সেই সিস্টেমে যা ইনস্টল রয়েছে তা পরিবর্তন করতে পারবেন না what ।

অবশ্যই, আপনি বাশ সোর্স কোডটি ডাউনলোড করতে এবং স্ক্র্যাচ থেকে আপনার নিজস্ব ব্যাশ তৈরি করতে পারেন, ~/binউদাহরণস্বরূপ এটি রেখে । এবং আপনি প্রথম এন্ট্রি হিসাবে অন্তর্ভুক্ত করতে ( যেমন প্রসারিত হবে না ) $PATHআপনার .bash_profileফাইলে আপনার পরিবর্তনশীলও সংশোধন করতে পারেন । আপনি যদি এখন কল করেন , শেলটি প্রথমে এটিটিকে ক্রমে সন্ধান করবে , সুতরাং এটিটি শুরু হয় যেখানে এটি আপনার সন্ধান করবে । যদি স্ক্রিপ্টগুলি ব্যবহারের জন্য অনুসন্ধান করে তবে একই জিনিস ঘটে , তাই এই স্ক্রিপ্টগুলি এখন আপনার কাস্টম বিল্ডটি ব্যবহার করে আপনার সিস্টেমে কাজ করবে ।~/binPATH=$HOME/bin:$PATH~$PATHbash$PATH~/binbashbash#!/usr/bin/env bashbash

একটি খারাপ দিক হ'ল এটি অপ্রত্যাশিত আচরণের দিকে পরিচালিত করতে পারে, যেমন একই মেশিনে একই স্ক্রিপ্ট বিভিন্ন পরিবেশের জন্য বিভিন্ন দোভাষী বা বিভিন্ন অনুসন্ধানের পথ ব্যবহারকারীদের সাথে চলতে পারে, যার ফলে সমস্ত ধরণের মাথা ব্যথা হয় aches

এর সবচেয়ে বড় ক্ষতিটি envহ'ল কিছু সিস্টেম কেবল একটি যুক্তির অনুমতি দেয়, সুতরাং আপনি এটি করতে পারবেন না #!/usr/bin/env <interpreter> <arg>, কারণ সিস্টেমগুলি <interpreter> <arg>একটি যুক্তি হিসাবে দেখবে (তারা এটিকে এমন আচরণ করবে যেমন অভিব্যক্তিটি উদ্ধৃত হয়েছিল) এবং এইভাবে envনামের একজন দোভাষীর সন্ধান করবে <interpreter> <arg>। মনে রাখবেন যে এটি envকমান্ড নিজেই কোনও সমস্যা নয়, যা সর্বদা একাধিক পরামিতিগুলি অতিক্রম করার অনুমতি দেয় কিন্তু সিস্টেমের শেবাং পার্সারের সাহায্যে কল করার আগেও এই লাইনটি পার্স করে env। এদিকে বেশিরভাগ সিস্টেমে এটি স্থির করা হয়েছে তবে যদি আপনার স্ক্রিপ্টটি অতি পোর্টেবল হতে চায় তবে আপনি নির্ভর করতে পারবেন না যে এটি আপনার চলমান সিস্টেমে স্থির হয়ে গেছে।

এটিতে সুরক্ষা সম্পর্কিত প্রভাব থাকতে পারে, যেমন যদি sudoপরিবেশকে পরিষ্কার করার জন্য কনফিগার করা না হয় বা $PATHপরিষ্কার থেকে বাদ দেওয়া হয়। আমি এটি প্রদর্শন করতে দিন:

সাধারণত /binএকটি সুরক্ষিত জায়গা, কেবল rootসেখানে কিছু পরিবর্তন করতে সক্ষম। আপনার হোম ডিরেক্টরিটি নয়, যদিও আপনি চালিত কোনও প্রোগ্রাম এতে পরিবর্তন করতে সক্ষম। এর অর্থ এই যে দূষিত কোডটি bashকোনও লুকানো ডিরেক্টরিতে একটি জাল স্থাপন করতে পারে , আপনার .bash_profileনিজের মধ্যে ডিরেক্টরিটি অন্তর্ভুক্ত করতে সংশোধন করতে পারে $PATH, তাই সমস্ত স্ক্রিপ্ট ব্যবহার করে #!/usr/bin/env bashসেই নকলটি চলবে bash। যদি sudoরাখে তবে $PATHআপনি বড় সমস্যায় পড়েছেন।

উদাহরণস্বরূপ বিবেচনা করুন কোনও সরঞ্জাম ~/.evil/bashনিম্নলিখিত সামগ্রীগুলির সাথে একটি ফাইল তৈরি করে :

#!/bin/bash

if [ $EUID -eq 0 ]; then
  echo "All your base are belong to us..."
  # We are root - do whatever you want to do
fi

/bin/bash "$@"

আসুন একটি সহজ স্ক্রিপ্ট তৈরি করুন sample.sh:

#!/usr/bin/env bash

echo "Hello World"

ধারণার প্রমাণ (এমন একটি সিস্টেমে sudoরাখে $PATH):

$ ./sample.sh
Hello World

$ sudo ./sample.sh
Hello World

$ export PATH="$HOME/.evil:$PATH"

$ ./sample.sh
Hello World

$ sudo ./sample.sh
All your base are belong to us...
Hello World

সাধারণত ক্লাসিক শেলগুলি সমস্তই অবস্থিত হওয়া উচিত /binএবং যদি আপনি যে কোনও কারণেই সেগুলি সেখানে রাখতে চান না, তবে /binতাদের আসল অবস্থানগুলিতে (বা সম্ভবত /binনিজেই একটি সিমলিংক) পয়েন্টে কোনও সিমলিংক স্থাপন করা আসলেই সমস্যা নয় so আমি সবসময় #!/bin/shএবং সাথে যেতে হবে #!/bin/bash। এখানে আরও অনেক কিছু রয়েছে যা যদি এগুলি আর কাজ না করে তবে ভেঙে যায়। এটি এমন নয় যে পসিএক্সের এই অবস্থানের প্রয়োজন হবে (পসিক্স পাথের নামগুলিকে প্রমিত করে না এবং এটি শেবাং বৈশিষ্ট্যটিকে মোটেই মানায় না) তবে তারা এতটাই সাধারণ, যে কোনও সিস্টেম কোনও প্রস্তাব না /bin/shদিলেও সম্ভবত এটি বুঝতে পারে #!/bin/shএবং এটি দিয়ে কী করবেন তা জানুন এবং এটি কেবল বিদ্যমান কোডের সাথে সামঞ্জস্যের জন্যই হতে পারে।

তবে পার্ল, পিএইচপি, পাইথন বা রুবির মতো আরও আধুনিক, অ-মানক, alচ্ছিক দোভাষীদের জন্য এটি কোথায় অবস্থিত হবে তা সত্যই নির্দিষ্ট করে বলা হয়নি। তারা হতে পারে /usr/binকিন্তু তারা পাশাপাশি হতে পারে /usr/local/binবা একটি সম্পূর্ণ ভিন্ন অনুক্রমের শাখা (ইন /opt/..., /Applications/..., ইত্যাদি)। এজন্য এগুলি প্রায়শই #!/usr/bin/env xxxশেবাং সিনট্যাক্স ব্যবহার করে ।


4

আমি এটি দরকারী হিসাবে মনে করি, কারণ যখন আমি এনভিভি সম্পর্কে জানতাম না, স্ক্রিপ্ট লিখতে শুরু করার আগে আমি এটি করছিলাম:

type nodejs > scriptname.js #or any other environment

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

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