"#" কেন "#"! / বিন / শ - "শেবাং?


27
#! / বিন / এস -

হয় (বা কমপক্ষে ছিল) প্রায়শই প্রস্তাবিত শেবাং দ্বারা কোনও স্ক্রিপ্ট দ্বারা ব্যাখ্যা করার জন্য দেওয়া হয় /bin/sh

শুধু #! /bin/shবা কেন নয় #!/bin/sh?

এটা কি -জন্য?

উত্তর:


37

আপনার লেখার দরকার পড়ার কারণ এটি একই কারণ:

rm -- *.txt

এবং না

rm *.txt

যতক্ষণ না আপনি কেউই নিশ্চিত করতে পারে না .txtবর্তমান ডিরেক্টরির সকল ফাইলের একটি নাম যে দিয়ে শুরু হয় আছে -

ইন:

rm <arg>

<arg>যদি এটি শুরু হয় -বা অন্যথায় সরানোর জন্য কোনও ফাইল হিসাবে বিবেচিত হয় । মধ্যে

rm - <arg>

argফাইলটি শুরু হয় কিনা তা নির্বিশেষে অপসারণের জন্য এটি সর্বদা ফাইল হিসাবে বিবেচিত হয় -

এটা একই sh

যখন কেউ একটি স্ক্রিপ্ট কার্যকর করে যা দিয়ে শুরু হয়

#! /bin/sh

সাধারণত:

execve("path/to/the-script", ["the-script", "arg"], [environ])

সিস্টেম এটিকে রূপান্তরিত করে:

execve("/bin/sh", ["/bin/sh", "path/to/the-script", "arg"], [environ])

path/to/the-scriptসাধারণত কিছু স্ক্রিপ্ট লেখক নিয়ন্ত্রণে নয়। স্ক্রিপ্টের অনুলিপি কোথায় বা কোন নামে সংরক্ষণ করা হবে তা লেখক ভবিষ্যদ্বাণী করতে পারবেন না। বিশেষত, তারা গ্যারান্টি দিতে পারে না যে যার path/to/the-scriptসাথে এটি বলা হয় এটি দিয়ে শুরু হবে না -(বা এটি +যা সমস্যাও রয়েছে sh)। এজন্য বিকল্পগুলির শেষ চিহ্নিত করতে আমাদের এখানে প্রয়োজন need-

উদাহরণস্বরূপ, আমার সিস্টেমে zcat(আসলে অন্যান্য স্ক্রিপ্টগুলির মতো) একটি স্ক্রিপ্টের একটি উদাহরণ যা সেই প্রস্তাবটি অনুসরণ করে না:

$ head -n1 /bin/zcat
#!/bin/sh
$ mkdir +
$ ln -s /bin/zcat +/
$ +/zcat
/bin/sh: +/: invalid option
[...]

এখন আপনি জিজ্ঞাসা করতে পারেন কেন #! /bin/sh -এবং না #! /bin/sh --?

#! /bin/sh --পসিক্স শেলগুলির সাথে কাজ করার সময় , এটি #! /bin/sh -আরও বহনযোগ্য; বিশেষত প্রাচীন সংস্করণগুলিতে sh। বিকল্প হিসাবে শেষের হিসাবে এবং shচিকিত্সা -করা এবং দীর্ঘ সময় দ্বারা বিকল্পগুলির শেষ চিহ্নিত করার জন্য getopt()সাধারণ ব্যবহার --। বোর্ন শেল যেভাবে (70 এর দশকের শেষভাগ থেকে) তার যুক্তিগুলি বিশ্লেষণ করেছে, যদি প্রথম শুরু হয় তবে এটি শুরু হলে বিকল্পগুলির জন্য বিবেচনা করা হত -। এর পরে সমস্ত অক্ষর -বিকল্প নাম হিসাবে গণ্য হবে; এর পরে যদি কোনও চরিত্র না থাকে তবে -কোনও বিকল্প ছিল না। এই আটকে এবং পরবর্তীকালে বোর্নের মতো শেলগুলি -বিকল্পগুলির শেষ চিহ্নিত করার উপায় হিসাবে স্বীকৃতি দেয় ।

বোর্ন শেলটিতে (তবে আধুনিক বোর্নের মতো শেলগুলিতে নয়) #! /bin/sh -eufসমস্যাটি প্রায়শই কাজ করবে কারণ বিকল্পগুলির জন্য শুধুমাত্র প্রথম যুক্তি বিবেচনা করা হয়েছিল।

এখন, কেউ বলতে পারে যে আমরা এখানে পেডেন্টিক হচ্ছি এবং এটিও কেন আমি উপরের তির্যকটিতে প্রয়োজনীয়তা লিখেছি :

  1. তাদের ডান মনের কেউই কোনও স্ক্রিপ্ট কল করতে শুরু করবে না এমন কিছু দিয়ে শুরু করবে -বা এমন ডিরেক্টরিতে রাখবে +না যার নাম দিয়ে শুরু হয় -বা +
  2. এমনকি যদি তারা তা করে তবে প্রথমে তারা যুক্তি দিত যে তারা কেবল নিজেরাই দোষ দিতে পারে, তবে আপনি যখন কোনও স্ক্রিপ্ট শুরু করেন তখন প্রায়শই না এটি শেল থেকে বা execvp()/ execlp()-টাইপ ফাংশন থেকে আসে। এবং যে ক্ষেত্রে, সাধারণত তুমি তাদের ডাকা হয় যেমন the-scriptজন্য এটা তাকিয়ে করা $PATHযে ক্ষেত্রে পাথ যুক্তি execve()সিস্টেম কল সাধারণত দিয়ে শুরু করবো /(শুধুমাত্র -কিংবা +) অথবা হিসাবে ./the-scriptযদি আপনি চান the-scriptবর্তমান ডিরেক্টরির মধ্যে চালানো যাবে (এবং তারপর পথ দিয়ে শুরু হয় ./, না -না +পারেন)।

এখন তাত্ত্বিক নির্ভুলতার ইস্যুটির পাশাপাশি আরও একটি কারণ রয়েছে #! /bin/sh -যা ভাল অনুশীলন হিসাবে সুপারিশ করা হয়েছিল । এবং এটি এমন এক সময়ে ফিরে যায় যেখানে বেশ কয়েকটি সিস্টেম এখনও সেটুইড স্ক্রিপ্টগুলি সমর্থন করে।

আপনার যদি এমন কোনও স্ক্রিপ্ট থাকে যা এতে অন্তর্ভুক্ত থাকে:

#! /bin/sh
/bin/echo "I'm running as root"

এবং সেই স্ক্রিপ্টটি -r-sr-xr-x root binকোনও সাধারণ ব্যবহারকারীর দ্বারা কার্যকর করা হলে, সেই সিস্টেমে মূল নির্ধারিত ( অনুমতি সহকারে ) সেট করা হয়েছিল

execve("/bin/sh", ["/bin/sh", "path/to/the-script"], [environ])

হিসাবে করা হবে root!

যদি ব্যবহারকারী একটি সিমলিংক তৈরি করে /tmp/-i -> path/to/the-scriptএবং এটি কার্যকর করে -i, তবে এটি হিসাবে একটি ইন্টারেক্টিভ শেল ( /bin/sh -i) শুরু করবে root

-প্রায় কাজ করবে যে (এটি প্রায় কাজ করবে না জাতি শর্ত ইস্যু , অথবা সত্য যে কিছু shকিছু মত বাস্তবায়নের ksh88ভিত্তিক বেশী ছাড়া স্ক্রিপ্ট আর্গুমেন্ট অনুসন্ধান করবে /মধ্যে $PATHযদিও)।

আজকাল, সম্ভবত কোনও সিস্টেম সেটুয়েড স্ক্রিপ্টকে আর সমর্থন করে না, এবং এখনও কিছু (সাধারণত ডিফল্ট হিসাবে হয় না) কিছু করে শেষ করে execve("/bin/sh", ["/bin/sh", "/dev/fd/<n>", arg])(যেখানে <n>স্ক্রিপ্টে পড়ার জন্য কোনও ফাইল বর্ণনাকারী খোলা থাকে) যা এই সমস্যাটি এবং উভয় ক্ষেত্রেই কাজ করে জাতি শর্ত.

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

এছাড়াও

#! /usr/bin/awk -f
#! /usr/bin/sed -f

যেমন পরবর্তী যুক্তি একটি আর্গুমেন্ট হিসাবে বিবেচনা করা হয় সমস্যা আছে না -fকোনো ক্ষেত্রে বিকল্প, কিন্তু এটি এখনও কাজ যদি না path/to/scriptহয় -(যা ক্ষেত্রে, যার সাথে সবচেয়ে বেশি sed/ awkবাস্তবায়নের, sed/ awkথেকে কোড পড়া না -ফাইল, কিন্তু পরিবর্তে stdin থেকে)।

আরও মনে রাখবেন যে বেশিরভাগ সিস্টেমে কেউ ব্যবহার করতে পারে না:

#! /usr/bin/env sh -
#! /usr/bin/perl -w --

বেশিরভাগ সিস্টেমে শেবাং প্রক্রিয়া ইন্টারপ্রিটার পাথের পরে কেবলমাত্র একটি যুক্তিকে মঞ্জুরি দেয় ।

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

ইউনিক্স শেবাং সম্পর্কে একটি খুব ভাল রেফারেন্স https://www.in-ulm.de/~mascheck/various/shebang এ পাওয়া যাবে


1
# এর সাথে কি কোনও প্রাসঙ্গিকতা আছে?
জো

1
@ জো, হ্যাঁ, অবশ্যই bashঅন্যান্য শেলের মতো বিকল্পগুলি গ্রহণ করে। বোর্ন-জাতীয় এবং পসিক্স শেল হওয়া, এবং bashউভয়ই গ্রহণ করে । #! /bin/bash -#! /bin/bash --
স্টাফেন চেজেলাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.