আমার শেবাং হিসাবে "#! / Usr / bin / env NAME" এর পরিবর্তে "#! / Usr / bin / env NAME" ব্যবহার করা ভাল কেন?


458

আমি লক্ষ্য করেছি যে আমি অন্যের কাছ থেকে প্রাপ্ত কিছু স্ক্রিপ্টগুলিতে শেবাং রয়েছে #!/path/to/NAMEযখন অন্যরা (একই সরঞ্জাম, NAME) ব্যবহার করে শেবাং রয়েছে #!/usr/bin/env NAME

উভয়ই ঠিকমতো কাজ করছে বলে মনে হচ্ছে। টিউটোরিয়ালগুলিতে (উদাহরণস্বরূপ পাইথন-তে) একটি পরামর্শ বলে মনে হচ্ছে যে পরবর্তী শিবাং আরও ভাল। তবে, আমি কেন পুরোপুরি বুঝতে পারছি না?

আমি বুঝতে পারি যে, দ্বিতীয় শিবাংটি ব্যবহার করতে, নাম অবশ্যই প্যাথএইচএইচ মধ্যে থাকতে হবে যদিও প্রথম শেবাংয়ের এই বিধিনিষেধ নেই।

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

আমার প্রশ্ন হ'ল প্রথম শেবাং কেন দ্বিতীয়টির চেয়ে পছন্দ হয়?



@ দি জিইকো 61১: আমার ক্ষেত্রে আমার কিছু ভেঙে গেছে এবং কিছু পরিবর্তনশীল vর্ষাভুক্ত ছিল না। সুতরাং env সঠিকভাবে লোড হয়েছে কিনা তা যাচাই করতে আমি এই শেবাংটি ব্যবহার করার পরামর্শ দিই।
গিগামেগস

উত্তর:


462

এটি অগত্যা ভাল না।

এর সুবিধাটি #!/usr/bin/env pythonহ'ল এটি pythonব্যবহারকারীর মধ্যে প্রথম কার্যকর হওয়া যা ব্যবহার করবে তা ব্যবহার করবে $PATH

অসুবিধা এর #!/usr/bin/env pythonএটি ব্যবহার করা হবে যাই হোক না কেন হয় pythonএক্সিকিউটেবল ব্যবহারকারীর প্রথম প্রদর্শিত হবে $PATH

এর অর্থ হ'ল স্ক্রিপ্টটি কে চালায় তার উপর নির্ভর করে আলাদা আচরণ করতে পারে। একটি ব্যবহারকারীর জন্য, এটি /usr/bin/pythonওএসের সাথে ইনস্টল হওয়াটি ব্যবহার করতে পারে । অন্যের জন্য, এটি এমন একটি পরীক্ষামূলক ব্যবহার করতে পারে /home/phred/bin/pythonযা পুরোপুরি সঠিকভাবে কাজ করে না।

যদি pythonশুধুমাত্র ইনস্টল করা /usr/local/bin, যে ব্যবহারকারী নেই /usr/local/binমধ্যে $PATHএমনকি স্ক্রিপ্ট চালাতে পারবেন হবে না। (এটি সম্ভবত আধুনিক সিস্টেমে খুব বেশি সম্ভাবনাযুক্ত নয়, তবে এটি আরও বেশি অস্পষ্ট দোভাষীর পক্ষে সহজেই ঘটতে পারে))

নির্দিষ্ট সিস্টেমে#!/usr/bin/python স্ক্রিপ্টটি চালানোর জন্য কোন দোভাষী ব্যবহার করা হবে তা নির্দিষ্ট করে আপনি নির্দিষ্ট করে ।

আর একটি সম্ভাব্য সমস্যা হ'ল #!/usr/bin/envকৌশলটি আপনাকে ইন্টিপ্লেটারে যুক্তি দেয় না (স্ক্রিপ্টের নাম বাদে , যা স্পষ্টভাবে পাস করা হয়)। এটি সাধারণত কোনও সমস্যা নয়, তবে তা হতে পারে। অনেক পার্ল স্ক্রিপ্টগুলি দিয়ে লেখা হয় #!/usr/bin/perl -wতবে use warnings;এটি সুপারিশ করা প্রতিস্থাপন হ'ল দিনগুলিতে। Csh স্ক্রিপ্টগুলি ব্যবহার করা উচিত #!/bin/csh -f- তবে csh স্ক্রিপ্টগুলি প্রথম স্থানে সুপারিশ করা হয় না । তবে এর অন্যান্য উদাহরণও থাকতে পারে।

আমি যখন একটি নতুন সিস্টেমে অ্যাকাউন্ট সেট আপ করি তখন একটি ব্যক্তিগত উত্স নিয়ন্ত্রণ সিস্টেমে আমার কাছে প্রচুর পার্ল স্ক্রিপ্ট রয়েছে। আমি একটি ইনস্টলার স্ক্রিপ্ট ব্যবহার করি যা #!প্রতিটি স্ক্রিপ্টের লাইনটি আমার মধ্যে ইনস্টল করার সাথে সাথে এটি পরিবর্তন করে $HOME/bin। (আমাকে #!/usr/bin/perlইদানীং ব্যতীত অন্য কিছু ব্যবহার করতে হয় নি ; এটি বারবার ফিরে যায় যখন পার্ল প্রায়শই ডিফল্টরূপে ইনস্টল করা হত না))

একটি ছোট্ট বিন্দু: #!/usr/bin/envকৌশলটি তাত্ক্ষণিকভাবে envকমান্ডটির অপব্যবহার , যা মূলত পরিবর্তিত পরিবেশের সাথে একটি আদেশ সঞ্চার করার উদ্দেশ্যে (নামটি ইঙ্গিত করা হয়েছিল)। তদুপরি, কিছু পুরানো সিস্টেমে (সুনোস 4 সহ, যদি আমি সঠিকভাবে স্মরণ করি) এর মধ্যে envকমান্ডটি নেই /usr/bin। এগুলির কোনওটিরই উল্লেখযোগ্য উদ্বেগ হওয়ার সম্ভাবনা নেই। envএইভাবে কাজ করে, প্রচুর স্ক্রিপ্টগুলি #!/usr/bin/envকৌশলটি ব্যবহার করে এবং ওএস সরবরাহকারীরা এটিকে ভেঙে ফেলার জন্য কিছু করতে পারে না। এটা তোলে পারে কোনো সমস্যা হবে যদি আপনি আপনার স্ক্রিপ্ট সত্যিই একটি পুরাতন সিস্টেমে চালাতে চান, তখন কিন্তু আপনি এটিকে যেকোনোভাবে পরিবর্তন করতে প্রয়োজন সেসময়।

আরেকটি সম্ভাব্য সমস্যা, (সোপালাজো ডি অ্যারিরেজকে ধন্যবাদ মন্তব্যগুলিতে উল্লেখ করার জন্য) যে ক্রোন জবস একটি সীমাবদ্ধ পরিবেশ নিয়ে চলে। বিশেষত, $PATHসাধারণত কিছু /usr/bin:/bin। সুতরাং যদি অনুবাদক ধারণকারী ডিরেক্টরিটি যদি সেই ডিরেক্টরিগুলির মধ্যে একটিতে না ঘটে, এমনকি এটি $PATHযদি কোনও ব্যবহারকারীর শেলের মধ্যে আপনার ডিফল্ট থাকে , তবে /usr/bin/envকৌশলটি কাজ করবে না। আপনি সঠিক পথটি নির্দিষ্ট করতে পারেন, বা সেট করতে আপনার ক্রন্টবটিতে একটি লাইন যুক্ত করতে পারেন $PATH( বিশদর জন্য man 5 crontab)।


4
যদি / usr / bin / perl পার্ল হয় 5.8, OME হোম / বিন / পার্ল 5.12 এবং স্ক্রিপ্টের মধ্যে 5.12 হার্ডকোড / ইউএসআর / বিন / পার্লের প্রয়োজন হয়, স্ক্রিপ্টটি চালানো বড় ব্যথা হতে পারে। আমি প্যাথ থেকে / ইউএসআর / বিন / এনভিভ পার্ল গ্র্যাব পার্লের সমস্যা খুব কমই দেখেছি, তবে এটি প্রায়শই সহায়ক। এবং এটি এক্সিকিউট হ্যাকের চেয়ে অনেক সুন্দর!
উইলিয়াম পার্সেল

8
এটি লক্ষণীয় যে, আপনি যদি একটি নির্দিষ্ট দোভাষী ব্যবহার করতে চান তবে / usr / bin / env আরও ভাল। কারণ সাধারণত হয় একাধিক অনুবাদক সংস্করণ আপনার মেশিনে perl5, perl5.12, perl5.10, python3.3 নামে, python3.32, ইত্যাদি উপর এবং যদি আপনার অ্যাপ শুধু তাই নির্দিষ্ট সংস্করণের উপর পরীক্ষা করা হয়েছে ইনস্টল, আপনি কি এখনও নির্দিষ্ট করতে পারেন #! / usr / bin / env perl5.12 এবং ঠিক আছে যদি এমনকি ব্যবহারকারী এটি কোথাও অস্বাভাবিকভাবে ইনস্টল করেছেন। আমার অভিজ্ঞতায়, 'পাইথন' সাধারণত সিস্টেম স্ট্যান্ডার্ড সংস্করণের (কেবলমাত্র সিস্টেমে অতি সাম্প্রতিক সংস্করণ নয়) একটি সিমিলিংক।
মূল

6
@ রুট: পার্লের জন্য, সেই উদ্দেশ্যে কিছুuse v5.12; কাজ করে । এবং সিস্টেমে পার্ল 5.14 তবে 5.12 না থাকলে ব্যর্থ হবে। পাইথন 2 বনাম 3 এর জন্য এবং সম্ভবত এটি কাজ করবে। #!/usr/bin/env perl5.12#!/usr/bin/python2#!/usr/bin/python3
কিথ থম্পসন

3
@ গুডপারসন: ধরুন আমি ইনস্টল করার জন্য একটি পার্ল স্ক্রিপ্ট লিখেছি /usr/local/bin। আমি জানি যে এটি সঠিকভাবে সাথে কাজ করে /usr/bin/perl। এলোমেলো কিছু র্যান্ডম ব্যবহারকারী তার বা তার মধ্যে যা ঘটে তার সাথে এটি কাজ করে কিনা আমার কোনও ধারণা নেই । হয়তো কেউ পার্লের কিছু প্রাচীন সংস্করণ নিয়ে পরীক্ষা নিরীক্ষা করছে; যেহেতু আমি নির্দিষ্ট করেছি , আমার স্ক্রিপ্ট (যা ব্যবহারকারীর জানা নেই বা যত্ন করা পার্ল স্ক্রিপ্টও নয়) কাজ করা বন্ধ করবে না। perl$PATH#!/usr/bin/perl
কিথ থম্পসন

5
যদি এটি কাজ করে না /usr/bin/perl, আমি খুব তাড়াতাড়ি এটি সন্ধান করব এবং এটি আপডেট রাখার দায়িত্ব সিস্টেমের মালিক / প্রশাসকের আপনি যদি আমার নিজের স্ক্রিপ্টটি নিজের পার্ল দিয়ে চালাতে চান তবে নিখরচায় একটি অনুলিপি সংশোধন করুন এবং এটির মাধ্যমে আবেদন করুন perl foo। (এবং আপনি এই সম্ভাবনাটি বিবেচনা করতে পারেন যে 55 জন লোক যারা উত্তরটি উত্তর দিয়েছিল তাদেরও একটি বা দুটি জিনিস জানা থাকতে পারে you're সম্ভবত এটি সম্ভব যে আপনি ঠিক আছেন এবং তারা সকলেই ভুল, তবে আমি যেভাবে বাজি ধরছি তা নয় not)
কীথ থম্পসন

101

কারণ / usr / bin / env আপনার ব্যাখ্যা করতে পারে $PATHযা স্ক্রিপ্টগুলিকে আরও বহনযোগ্য করে তোলে।

#!/usr/local/bin/python

অজগরটি / usr / স্থানীয় / বিনে ইনস্টল করা হলে কেবল আপনার স্ক্রিপ্টটি চালানো হবে installed

#!/usr/bin/env python

আপনার ব্যাখ্যা করবে $PATHএবং আপনার কোনও ডিরেক্টরিতে অজগর খুঁজে পাবে $PATH

সুতরাং আপনার স্ক্রিপ্ট আরো পোর্টেবল, এবং সিস্টেম যেখানে পাইথন যেমন ইনস্টল না হওয়া পর্যন্ত পরিমার্জন ছাড়া কাজ করবে /usr/bin/python, অথবা /usr/local/bin/python, অথবা এমনকি কাস্টম ডিরেক্টরি (যে এ যোগ করা হয়েছে $PATH), মত /opt/local/bin/python

পোর্টেবিলিটিই হ'ল envহার্ড কোডিং পাথগুলিতে পছন্দ করা একমাত্র কারণ ।


19
pythonএক্সিকিউটেবলের জন্য কাস্টম ডিরেক্টরিগুলি বিশেষত virtualenvব্যবহারের বৃদ্ধি হিসাবে সাধারণ ।
জিওনগ চিয়ামিয়াভ

1
কি সম্পর্কে #! python, কেন যে ব্যবহার করা হয় না?
ক্রিস্টিয়ানপ

6
#! pythonব্যবহৃত হয়নি কারণ আপনাকে পাইথন বাইনারি হিসাবে একই ডিরেক্টরিতে থাকতে হবে, যেহেতু খালি pythonশব্দটি ফাইলটির সম্পূর্ণ পথ হিসাবে ব্যাখ্যা করা হয়েছে। আপনার যদি বর্তমান ডিরেক্টরিতে পাইথন বাইনারি না থাকে তবে আপনি এর মতো একটি ত্রুটি পাবেন bash: ./script.py: python: bad interpreter: No such file or directory। এটি আপনি যেমন ব্যবহার করেছিলেন #! /not/a/real/path/python
টিম কেনেডি

47

প্রদত্ত সিস্টেমে পরম পাথ উল্লেখ করা আরও সুনির্দিষ্ট। খারাপ দিকটি এটি খুব সুনির্দিষ্ট। ধরুন আপনি বুঝতে পারছেন যে পার্লের সিস্টেম ইনস্টলেশনটি আপনার স্ক্রিপ্টগুলির জন্য খুব পুরানো এবং আপনি তার পরিবর্তে আপনার নিজের ব্যবহার করতে চান: তাহলে আপনাকে স্ক্রিপ্টগুলি সম্পাদনা করতে হবে এবং এতে পরিবর্তন #!/usr/bin/perlকরতে হবে #!/home/myname/bin/perl। সবচেয়ে খারাপ, যদি আপনার /usr/binকিছু মেশিনে, /usr/local/binঅন্যদের এবং /home/myname/bin/perlঅন্য মেশিনগুলিতে পার্ল থাকে তবে আপনাকে স্ক্রিপ্টগুলির পৃথক তিনটি অনুলিপি বজায় রাখতে হবে এবং প্রতিটি মেশিনে যথাযথ একটিকে সম্পাদন করতে হবে।

#!/usr/bin/envPATHখারাপ হলে বিরতি , তবে প্রায় কিছুই করে। খারাপের সাথে কাজ করার চেষ্টা PATHখুব কমই দরকারী, এবং ইঙ্গিত দেয় যে স্ক্রিপ্টটি যে সিস্টেমটি চলছে সে সম্পর্কে আপনি খুব কম জানেন, সুতরাং আপনি যে কোনও উপায়ের উপর নির্ভর করতে পারবেন না।

দুটি প্রোগ্রাম রয়েছে যার অবস্থান আপনি প্রায় প্রতিটি ইউনিক্স বৈকল্পিকের উপর নির্ভর করতে পারেন: /bin/shএবং /usr/bin/env। কিছু অস্পষ্ট এবং বেশিরভাগ অবসরপ্রাপ্ত ইউনিক্স রূপগুলি না /bin/envথাকলেও আপনার এগুলির /usr/bin/envমুখোমুখি হওয়ার সম্ভাবনা কম। আধুনিক ব্যবস্থাগুলি /usr/bin/envহুবহু কারণেই শেবাংগুলিতে এর ব্যাপক ব্যবহার রয়েছে। /usr/bin/envএমন একটি জিনিস যা আপনি বিশ্বাস করতে পারেন।

এ ছাড়া /bin/sh, আপনি কেবলমাত্র একবার শেবাংয়ের ক্ষেত্রে নিখুঁত পথ ব্যবহার করা উচিত যখন আপনার স্ক্রিপ্টটি বহনযোগ্য হিসাবে বোঝানো হয় না, তাই আপনি দোভাষীর জন্য একটি পরিচিত স্থানে গুনতে পারেন। উদাহরণস্বরূপ, কেবলমাত্র লিনাক্সে কাজ করে এমন ব্যাশ স্ক্রিপ্ট নিরাপদে ব্যবহার করতে পারে #!/bin/bash। একটি স্ক্রিপ্ট যা কেবলমাত্র ঘরে বসে ব্যবহারের উদ্দেশ্যে বোঝানো হয়েছে তা বাড়ির দোভাষী সংস্থার সম্মেলনে নির্ভর করতে পারে।

#!/usr/bin/envডাউনসাইড আছে। এটি একটি নিখুঁত পাথ নির্দিষ্ট করার চেয়ে আরও নমনীয় তবে তবুও দোভাষীর নাম জানা দরকার। মাঝেমধ্যে আপনি এমন একটি দোভাষী চালাতে চাইতে পারেন যা এর মধ্যে নেই $PATH, উদাহরণস্বরূপ স্ক্রিপ্টের সাথে সম্পর্কিত কোনও অবস্থানে। এই ধরনের ক্ষেত্রে, আপনি প্রায়শই একটি বহুবৃত্ত স্ক্রিপ্ট তৈরি করতে পারেন যা স্ট্যান্ডার্ড শেল এবং আপনার পছন্দসই দোভাষী দ্বারা উভয়ই ব্যাখ্যা করা যায়। উদাহরণস্বরূপ, করতে একটি পাইথন 2 স্ক্রিপ্ট সিস্টেম উভয় পোর্টেবল যেখানে pythonপাইথন 3 এবং python2পাইথন 2, এবং সিস্টেম যেখানে pythonপাইথন 2 এবং python2বিদ্যমান নয়:

#!/bin/sh
''':'
if type python2 >/dev/null 2>/dev/null; then
  exec python2 "$0" "$@"
else
  exec python "$0" "$@"
fi
'''
# real Python script starts here
def …

22

বিশেষত পার্লের #!/usr/bin/envজন্য, দুটি কারণে ব্যবহার করা খারাপ ধারণা।

প্রথমত, এটি বহনযোগ্য নয়। কিছু অস্পষ্ট প্ল্যাটফর্মের উপর env / usr / bin থাকে না। দ্বিতীয়ত, কিথ থম্পসন যেমন উল্লেখ করেছেন, এটি শেবাং লাইনে যুক্তি দিয়ে সমস্যা তৈরি করতে পারে। সর্বাধিক বহনযোগ্য সমাধানটি হ'ল:

#!/bin/sh
exec perl -x "$0" "$@"
#!perl

এটি কীভাবে কাজ করে তার বিশদগুলির জন্য 'পার্ল্ডোক পার্ল্রুন' দেখুন এবং এটি -x আর্গুমেন্ট সম্পর্কে কী বলে।


হুবহু আমি যে আনসারটি সন্ধান করছিলাম: পার্ল স্ক্রিপ্টের জন্য কীভাবে "শিবাং" লিখতে পারা যায় যা অতিরিক্ত আর্মেন্টগুলিকে পার্লে পাস করার অনুমতি দেয় (আপনার উদাহরণের শেষ লাইনটি অতিরিক্ত আর্গুমেন্ট গ্রহণ করে)।
AmokHuginnsson

15

উভয়ের মধ্যে পার্থক্য থাকার কারণ হ'ল স্ক্রিপ্টগুলি কীভাবে কার্যকর করা হয়।

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

#!bash

echo 'foo'

আপনি যখন এটি চালানোর চেষ্টা করবেন তখন আপনি এটির মতো একটি ত্রুটি ছাপতে পাবেন:

Failed to execute process './test.sh'. Reason:
The file './test.sh' does not exist or could not be executed.

যদি কোনও ফাইল নির্বাহযোগ্য হিসাবে চিহ্নিত হয় এবং #!এটি একটি দিয়ে শুরু হয় , কার্নেল (যা $PATHবর্তমান ডিরেক্টরি সম্পর্কে বা না জানে : এগুলি ব্যবহারকারী-ভূমি ধারণা) একটি পরম পথ ব্যবহার করে কোনও ফাইল সন্ধান করবে। যেহেতু একটি নিখুঁত পথ ব্যবহার করা সমস্যাযুক্ত (অন্যান্য উত্তরে উল্লিখিত), কেউ একটি কৌশল নিয়ে এসেছিল: আপনি /usr/bin/envকিছু ব্যবহার করে চালাতে (যা প্রায় that অবস্থানে প্রায় সবসময়ই) চালাতে পারেন $PATH


11

ব্যবহারে আরও দুটি সমস্যা রয়েছে #!/usr/bin/env

  1. এটি দোভাষীর পুরো পথ নির্দিষ্ট করার সমস্যাটি সমাধান করে না, এটি কেবল এটিকে সরিয়ে দেয় env

    envপাইথন বা অজগরের মধ্যে গ্যারান্টিযুক্ত তার /usr/bin/envচেয়ে বেশি নিশ্চয়তা নেই ।bash/bin/bash/usr/bin/python

  2. env দোভাষী (e..g বাশ বা পাইথন) এর সাথে এআরজিভি [0] ওভাররাইট করে।

    এটি আপনার স্ক্রিপ্টের নাম উপস্থিত হতে বাধা দেয়, উদাহরণস্বরূপ, psআউটপুট (বা কীভাবে প্রদর্শিত হবে / যেখানে পরিবর্তন হয়) এবং এটি এটি খুঁজে পাওয়া অসম্ভব করে তোলে যেমন,ps -C scriptname.sh

[আপডেট 2016-06-04]

এবং তৃতীয় সমস্যা:

  1. আপনার पथপথ পরিবর্তন করা কেবলমাত্র কোনও স্ক্রিপ্টের প্রথম লাইন সম্পাদনা করার চেয়ে বেশি কাজ, বিশেষত যখন এই জাতীয় সম্পাদনাগুলি স্ক্রিপ্ট করা তুচ্ছ। উদাহরণ:

    printf "%s\n" 1 i '#!'$(type -P python2) . w | ed foo.py

    Directory PATH- তে ডিরেক্টরি অন্তর্ভুক্ত করা বা প্রাক-মুলতুবি রাখা মোটামুটি সহজ (যদিও আপনাকে এখনও এটি স্থায়ী করার জন্য কোনও ফাইল সম্পাদনা করতে হবে - আপনার ~/.profileবা যাই হোক না কেন - এবং এটি সম্পাদনা করা খুব সহজেই সম্পাদনা করা যায় কারণ প্যাথ স্ক্রিপ্টের যে কোনও জায়গায় সেট করা যেতে পারে because , প্রথম লাইনে নয়)।

    PATH ডিরেক্টরিগুলির ক্রম পরিবর্তন করা উল্লেখযোগ্যভাবে আরও বেশি কঠিন .... এবং কেবল #!লাইন সম্পাদনা করার চেয়ে আরও শক্ত ।

    এবং আপনার এখনও অন্যান্য সমস্ত সমস্যা যা ব্যবহারের ফলে #!/usr/bin/envআপনাকে দেয়।

    @ জেলিয়াগ্রে একটি মন্তব্যে পরামর্শ দিয়েছেন যা #!/usr/bin/envআপনার স্ক্রিপ্টটি একাধিক দোভাষী দের সংস্করণ দিয়ে পরীক্ষা করার জন্য দরকারী, "কেবল তাদের প্যাথ / প্যাথ ক্রম পরিবর্তন করে"

    যদি আপনার এটি করার দরকার #!হয় তবে আপনার স্ক্রিপ্টের শীর্ষে কয়েকটি লাইন থাকা খুব সহজ (সেগুলি কেবল প্রথম লাইনের পরিবর্তে অন্য কোথাও মন্তব্য করতে পারেন) এবং আপনি এখন যেটি ব্যবহার করতে চান তা কাটা / অনুলিপি করুন এবং পেস্ট করুন প্রথম লাইন

    ইন vi, এটি কার্সারটি আপনার পছন্দসই #!রেখায় সরানোর মতো সহজ হবে , তারপরে টাইপ করুন dd1GPবা Y1GP। এমনকি সম্পাদক হিসাবে তুচ্ছ হিসাবে nano, এটি কপি এবং পেস্ট করতে মাউস ব্যবহার করতে কয়েক সেকেন্ড সময় লাগবে।


সামগ্রিকভাবে, ব্যবহারের সুবিধাগুলি #!/usr/bin/envসর্বনিম্ন ন্যূনতম এবং অবশ্যই অসুবিধাগুলি ছাড়িয়ে যাওয়ার কাছাকাছি আসবেনা। এমনকি "সুবিধার্থে" সুবিধাটি মূলত মায়াময়।

আইএমও, এটি একটি নির্দিষ্ট ধরণের প্রোগ্রামার দ্বারা প্রচারিত একটি নির্বোধ ধারণা, যিনি মনে করেন যে অপারেটিং সিস্টেমগুলি কাজ করার মতো জিনিস নয়, এগুলি প্রায় কাজ করার সমস্যা (বা সেরা উপেক্ষা করা) are

PS: একবারে একাধিক ফাইলের দোভাষীকে পরিবর্তন করতে এখানে একটি সহজ স্ক্রিপ্ট।

change-shebang.sh:

#!/bin/bash

interpreter="$1"
shift

if [ -z "$(type -P $interpreter)" ] ; then
  echo "Error: '$interpreter' is not executable." >&2
  exit 1
fi

if [ ! -d "$interpreter" ] && [ -x "$interpreter" ] ; then
  shebang='#!'"$(realpath -e $interpreter)" || exit 1
else
  shebang='#!'"$(type -P $interpreter)"
fi

for f in "$@" ; do
  printf "%s\n" 1 i "$shebang" . w | ed "$f"
done

এটি চালান, যেমন, change-shebang.sh python2.7 *.pyবাchange-shebang.sh $HOME/bin/my-experimental-ruby *.rb


4
এখানে আর কেউ এআরজিভি [0] সমস্যার উল্লেখ করেনি। এবং কেউ কোনও পন্থায় / পথ / টু / এনভিটি ইস্যুটি উল্লেখ করেনি যা এটি ব্যবহারের জন্য যুক্তির একটিকে সরাসরি সম্বোধন করে (যেমন বাশ বা পার্ল কোনও অপ্রত্যাশিত জায়গায় থাকতে পারে)।
কাস

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

3
নন-সিসাডমিনরা তাদের সিসাদমিনকে এটি করতে বলতে চাইতে পারে। অথবা তারা কেবল স্ক্রিপ্ট সম্পাদনা করতে এবং #!লাইনটি পরিবর্তন করতে পারে ।
কাশ

2
এটি হ'ল এনভিটি এড়াতে সহায়তা করছে: সায়সডমিন বা ওএসের ভিত্তিতে পাইথনের সাথে সম্পর্কিত নয় এমন কিছু নির্দিষ্ট প্রযুক্তি সম্পর্কিত জ্ঞান।
jlliagre

1
আমি আমি এই একটি হাজার হাজার গুণ ভোট দিন পারতাম, এটি আসলে একটি মহান উত্তর কারণ উভয় ক্ষেত্রেই - যদি কেউ ব্যবহার /usr/bin/envএবং আমি স্থানীয়ভাবে তা পরিত্রাণ পেতে প্রয়োজন, অথবা যদি তারা এটি ব্যবহার করা হয়নি এবং আমি তা যোগ করতে হবে। উভয় ক্ষেত্রেই ঘটতে পারে এবং তাই এই উত্তরে প্রদত্ত স্ক্রিপ্টগুলি টুলবক্সে থাকা একটি সম্ভাব্য দরকারী সরঞ্জাম।
জাস্টাইন

8

এখানে অন্য উদাহরণ যুক্ত করা হচ্ছে:

উদাহরণস্বরূপ আপনি envএকাধিক rvmপরিবেশের মধ্যে স্ক্রিপ্টগুলি ভাগ করতে চাইলে ব্যবহার করাও কার্যকর ।

এটি সিএমডি লাইনে চালানো, দেখায় যে #!/usr/bin/env rubyকোনও স্ক্রিপ্টের অভ্যন্তরে কখন রুবি সংস্করণ ব্যবহৃত হবে :

env ruby --version

অতএব, আপনি যখন ব্যবহার করবেন env, আপনি আপনার স্ক্রিপ্টগুলি পরিবর্তন না করে আরভিএম এর মাধ্যমে বিভিন্ন রুবি সংস্করণ ব্যবহার করতে পারেন।


1
// , চমৎকার ধারণা. একাধিক দোভাষী পুরো পয়েন্ট না কোড বিরতি, বা কোড উপর নির্ভর থাকতে হয় যে নির্দিষ্ট অনুবাদক
নাথান বাসানিজ

4

আপনি যদি নিজের জন্য বা আপনার কাজের জন্য এবং যে দোভাষীর কল করছেন তার জন্য যদি আপনি নিখুঁতভাবে লিখছেন তবে সর্বদা একই জায়গায় থাকবেন, সর্বত্র সরাসরি পথটি ব্যবহার করুন। অন্য সব ক্ষেত্রে ব্যবহার #!/usr/bin/env

এখানে কেন: আপনার পরিস্থিতিতে pythonদোভাষীটি একই জায়গায় ছিলেন আপনি নির্বিশেষে কোন সিনট্যাক্স ব্যবহার করেছেন তবে অনেকের পক্ষে এটি অন্য জায়গায় ইনস্টল করতে পারত। যদিও বেশিরভাগ বড় প্রোগ্রামিং ইন্টারপ্রেটার /usr/bin/অনেক নতুন সফ্টওয়্যারটিতে অবস্থিত তবে এটি ডিফল্ট /usr/local/bin/

আমি সর্বদা ব্যবহার করার পক্ষেও তর্ক করব #!/usr/bin/envকারণ আপনার যদি একই দোভাষীর একাধিক সংস্করণ ইনস্টল থাকে এবং আপনার শেলটি কোনটি ডিফল্ট হবে তা আপনি জানেন না, তবে আপনার সম্ভবত এটি ঠিক করা উচিত।


5
"অন্যান্য সমস্ত ক্ষেত্রে #! / Usr / bin / env" ব্যবহার খুব শক্ত। // যেমন @ কিথথম্পসন এবং অন্যরা উল্লেখ করেছেন, #! / Usr / bin / env এর অর্থ স্ক্রিপ্টটি কে / কীভাবে চালায় তার উপর নির্ভর করে আলাদা আচরণ করতে পারে। কখনও কখনও এই ভিন্ন আচরণটি সুরক্ষা বাগ হতে পারে। // উদাহরণস্বরূপ, সেটআপড বা সেটজিড স্ক্রিপ্টের জন্য "#! / Usr / bin / env python" কখনই ব্যবহার করবেন না, কারণ স্ক্রিপ্টের আবেদনকারী ব্যবহারকারী PATH এর "পাইথন" নামক একটি ফাইলে ম্যালওয়ার স্থাপন করতে পারে। সেটুইড / গিড স্ক্রিপ্টগুলি সর্বদা ভাল ধারণা কিনা তা ভিন্ন বিষয় a তবে অবশ্যই, নির্ধারিত কোনও সেটুইড / জিড ব্যবহারকারীর পরিবেশে বিশ্বাস করা উচিত নয়।
ক্রেজি গ্লিউ

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

3

বহনযোগ্যতা এবং সামঞ্জস্যতার কারণে এটি ব্যবহার করা ভাল

#!/usr/bin/env bash

পরিবর্তে

#!/usr/bin/bash

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

উদাহরণস্বরূপ ফ্রিবিএসডি সমস্ত সফ্টওয়্যার ইনস্টল করে, যা বেস সিস্টেমের অংশ নয়, / ইউএসআর / লোকাল / এ । যেহেতু বাশ বেস সিস্টেমের অংশ নয়, তাই বাশ বাইনারি / usr / স্থানীয় / বিন / ব্যাশে ইনস্টল করা আছে ।

আপনি যখন কোনও পোর্টেবল বাশ / সিএসএস / পার্ল / যে কোনও স্ক্রিপ্ট চান যা বেশিরভাগ লিনাক্স ডিস্ট্রিবিউশন এবং ফ্রিবিএসডি এর অধীনে চলতে থাকে, আপনি #! / Usr / bin / env ব্যবহার করা উচিত ।

আরও লক্ষ করুন, বেশিরভাগ লিনাক্স ইনস্টলেশনগুলি (হার্ড) এনভের বাইনারিটিকে / বিন / এনভ বা সফ্টলিঙ্কযুক্ত / ইউএসআর / বিনকে / বিনের সাথে সংযুক্ত করেছে যা শেবাং ব্যবহার করা উচিত নয় । সুতরাং #! / বিন / এনভী ব্যবহার করবেন না ।

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