#! / বিন / শ বনাম #! / বিন / বাশ সর্বাধিক বহনযোগ্যতার জন্য


36

আমি সাধারণত উবুন্টু LTS সার্ভার যা থেকে কি আমি সিমবলিক লিঙ্ক বুঝতে সাথে কাজ /bin/shকরার জন্য /bin/dash। অন্য অনেকগুলি ডিস্ট্রোস যদিও এতে সিমিলিং /bin/shথাকে /bin/bash

এটি থেকে আমি বুঝতে পারি যে কোনও স্ক্রিপ্ট যদি #!/bin/shউপরে ব্যবহার করে তবে এটি সমস্ত সার্ভারে একইভাবে চলতে পারে না?

যখন কোনও সার্ভারের মধ্যে those স্ক্রিপ্টগুলির সর্বাধিক বহনযোগ্যতা চান তখন কোন শেলটিতে স্ক্রিপ্টগুলির জন্য কোন শেল ব্যবহার করা উচিত?


বিভিন্ন শেলের মধ্যে সামান্য পার্থক্য রয়েছে। যদি পোর্টেবিলিটিটি আপনার পক্ষে সর্বাধিক গুরুত্বপূর্ণ হয় তবে #!/bin/shমূল শেলটি দেওয়া ছাড়া অন্য কিছু ব্যবহার করুন এবং ব্যবহার করবেন না।
থরবজর্ন রাভন অ্যান্ডারসন

উত্তর:


65

শেল স্ক্রিপ্টগুলির জন্য প্রায় চার স্তরের বহনযোগ্যতা রয়েছে (যতক্ষণ না শেবাং লাইন সম্পর্কিত):

  1. সর্বাধিক বহনযোগ্য: একটি #!/bin/shশেবাং ব্যবহার করুন এবং কেবল পসিক্স স্ট্যান্ডার্ডে নির্দিষ্ট বেসিক শেল সিনট্যাক্স ব্যবহার করুন । এটি কোনও পসিক্স / ইউনিক্স / লিনাক্স সিস্টেমে কাজ করা উচিত। (ঠিক আছে, সোলারিস 10 এবং এর আগে যার সত্যিকারের উত্তরাধিকার বোর্ন শেল ছিল, POSIX এর অনুমানযোগ্য হিসাবে অনুমান করে, যেমন /bin/sh))

  2. দ্বিতীয় সর্বাধিক বহনযোগ্য: একটি #!/bin/bash(বা #!/usr/bin/env bash) শেবাং লাইন ব্যবহার করুন, এবং ব্যাশ ভি 3 বৈশিষ্ট্যগুলিকে আটকে দিন। এটি ব্যাশযুক্ত যে কোনও সিস্টেমে কাজ করবে (প্রত্যাশিত স্থানে)।

  3. তৃতীয় সর্বাধিক বহনযোগ্য: একটি #!/bin/bash(বা #!/usr/bin/env bash) শেবাং লাইন ব্যবহার করুন এবং ব্যাশ ভি 4 বৈশিষ্ট্যগুলি ব্যবহার করুন। এটি ব্যাশ ভি 3 রয়েছে এমন কোনও সিস্টেমে ব্যর্থ হবে (উদাঃ ম্যাকোস, যা লাইসেন্সের কারণে এটি ব্যবহার করতে হবে)।

  4. সর্বনিম্ন বহনযোগ্য পোর্টেবল: একটি #!/bin/shশেবাং ব্যবহার করুন এবং POSIX শেল সিনট্যাক্সে ব্যাশ এক্সটেনশান ব্যবহার করুন। এটি / বিন / শের (যেমন সাম্প্রতিক উবুন্টু সংস্করণগুলির) জন্য বাশ ছাড়া অন্য কিছু রয়েছে এমন কোনও সিস্টেমে ব্যর্থ হবে। কখনও এই কাজ করবেন না; এটি কেবল একটি সামঞ্জস্যের সমস্যা নয়, এটি কেবল সাধারণ ভুল। দুর্ভাগ্যক্রমে, এটি একটি ত্রুটি যা বহু লোক তৈরি করে।

আমার সুপারিশ: প্রথম তিনটির মধ্যে সবচেয়ে রক্ষণশীল ব্যবহার করুন যা আপনাকে স্ক্রিপ্টের জন্য প্রয়োজনীয় সমস্ত শেল বৈশিষ্ট্য সরবরাহ করে। সর্বাধিক বহনযোগ্যতার জন্য, বিকল্প # 1 ব্যবহার করুন, তবে আমার অভিজ্ঞতায় কিছু বাশ বৈশিষ্ট্য (যেমন অ্যারেগুলি) যথেষ্ট সহায়ক যে আমি # 2 দিয়ে যাব।

আপনি সবচেয়ে খারাপ কাজটি করতে পারেন # 4, ভুল শেবাং ব্যবহার করে। আপনি যদি নিশ্চিত না হন যে কোন বৈশিষ্ট্যগুলি বেসিক পসিক্স এবং কোনটি ব্যাশ এক্সটেনশনগুলি হয় তবে তা বাশ শেবাং (যেমন বিকল্প # 2) দিয়ে আটকে থাকুন, বা খুব বেসিক শেল (আপনার উবুন্টু এলটিএস সার্ভারের ড্যাশের মতো) দিয়ে স্ক্রিপ্টটি পুরোপুরি পরীক্ষা করুন। উবুন্টু উইকিতে নজর রাখার জন্য বাশিজমের একটি ভাল তালিকা রয়েছে

ইতিহাস এবং ইউনিক্স এবং লিনাক্স প্রশ্নে শাঁসের মধ্যে পার্থক্য সম্পর্কে কিছু খুব ভাল তথ্য রয়েছে "sh সুসংগত হওয়ার অর্থ কী?" এবং স্ট্যাকওভারফ্লো প্রশ্ন "শ এবং বাশের মধ্যে পার্থক্য"

এছাড়াও, সচেতন থাকুন যে শেলটি কেবলমাত্র বিভিন্ন ব্যবস্থার মধ্যে পৃথক নয়; আপনি যদি লিনাক্স ব্যবহার করে থাকেন তবে আপনি জিএনইউ কমান্ডের সাথে ব্যবহার করেছেন, যার অনেকগুলি নন-স্ট্যান্ডার্ড এক্সটেনশন রয়েছে যা আপনি অন্যান্য ইউনিক্স সিস্টেমে খুঁজে পাবেন না (যেমন, বিএসডি, ম্যাকোস)। দুর্ভাগ্যক্রমে, এখানে সরল কোনও নিয়ম নেই, আপনি যে কমান্ডগুলি ব্যবহার করছেন তার জন্য আপনাকে কেবল তারতম্যের সীমাটি জানতে হবে।

: বহনযোগ্যতা পরিপ্রেক্ষিতে nastiest কমান্ড এক সবচেয়ে মৌলিক এক echo। আপনি যে কোনও সময় এটি কোনও বিকল্প (যেমন echo -nবা echo -e), বা মুদ্রণের জন্য স্ট্রিংয়ে কোনও পলায়ন (ব্যাকস্ল্যাশ) সহ ব্যবহার করুন , বিভিন্ন সংস্করণ বিভিন্ন জিনিস করবে। আপনি যখনই কোনও স্ট্রিং এর পরে লাইনফিড ছাড়াই মুদ্রণ করতে চান বা স্ট্রিংয়ের সাথে পালাতে চান তার printfপরিবর্তে ব্যবহার করুন (এবং এটি কীভাবে কাজ করে তা শিখুন - এটি এর চেয়ে জটিল echo)। psকমান্ড একটি জগাখিচুড়ি

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


12
চতুর্থ বিকল্পটি কেবল একটি ভুল ধারণা। দয়া করে এটি ব্যবহার করবেন না।
pabouk

3
@ পাবউক আমি সম্পূর্ণরূপে একমত, তাই আমি এই উত্তরটি পরিষ্কার করার জন্য আমার উত্তর সম্পাদনা করেছি।
গর্ডন ডেভিসন

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

2
আমি খুব সম্প্রতি আমার একটি স্ক্রিপ্ট নিয়ে # 4 এ পড়েছি এবং কেন এটি কাজ করছে না তা বুঝতে পারি না; সর্বোপরি, একই কমান্ডগুলি দৃly়তার সাথে কাজ করেছিল এবং আমি শেলটিতে সরাসরি চেষ্টা করার পরে আমি তাদের যা করতে চেয়েছিলাম ঠিক তা করেছিল did যত তাড়াতাড়ি আমি পরিবর্তন #!/bin/shকরতে #!/bin/bashযদিও, স্ক্রিপ্ট পুরোপুরি কাজ করেন। (আমার প্রতিরক্ষার পক্ষে, সেই স্ক্রিপ্টটি সময়ের সাথে বিবর্তিত হয়েছিল যা কেবলমাত্র শ-ইসেমস প্রয়োজন, বাশের মতো আচরণের উপর নির্ভর করে এমন একজনের কাছে।)
সিভিএন

2
@ মাইকেলKjörling (সত্য) বোর্ন শেল প্রায় কখনও লিনাক্স ডিস্ট্রিবিউশনগুলির সাথে বান্ডিল হয় না এবং যাইহোক পোসিক্স অনুগত নয়। পসিক্স স্ট্যান্ডার্ড শেলটি kshআচরণ থেকে তৈরি হয়েছিল , বোর্নের নয়। এফএইচএস অনুসরণ করে বেশিরভাগ লিনাক্স ডিস্ট্রিবিউশনগুলি /bin/shপসিক্স সামঞ্জস্যতা প্রদান করার জন্য তারা বেছে নেওয়া শেলের প্রতীকী লিঙ্ক হয়ে থাকে, সাধারণত bashবা dash
jlliagre

5

ইন ./configureস্ক্রিপ্ট নির্মাণের জন্য TXR ভাষা দেয়ঃ, আমি ভাল বহনযোগ্যতা জন্য নিম্নলিখিত প্রস্তাবনা পোষ্ট লিখেছেন। স্ক্রিপ্টটি #!/bin/shকোনও পসিক্স-কনফর্মিং পুরানো বোর্ন শেল হলেও নিজেই বুটস্ট্র্যাপ করবে । (আমি প্রতিটি সোলারিস 10 ভিএম-তে প্রকাশ করি)।

#!/bin/sh

# use your own variable name instead of txr_shell;
# adjust to taste: search for your favorite shells

if test x$txr_shell = x ; then
  for shell in /bin/bash /usr/bin/bash /usr/xpg4/bin/sh ; do
    if test -x $shell ; then
       txr_shell=$shell
       break
    fi
  done
  if test x$txr_shell = x ; then
    echo "No known POSIX shell found: falling back on /bin/sh, which may not work"
    txr_shell=/bin/sh
  fi
  export txr_shell
  exec $txr_shell $0 ${@+"$@"}
fi

# rest of the script here, executing in upgraded shell

এখানে ধারণাটি হ'ল আমরা যে অধীনে চলছি তার চেয়ে ভাল শেলটি আমরা খুঁজে পাই এবং সেই শেলটি ব্যবহার করে স্ক্রিপ্টটি পুনরায় কার্যকর করি। txr_shellএনভায়রনমেন্ট ভেরিয়েবল সেট করা থাকে, পুনরায় মৃত্যুদন্ড কার্যকর স্ক্রিপ্ট জানে যাতে এটি পুনরায় মৃত্যুদন্ড কার্যকর রিকার্সিভ উদাহরণ।

(আমার স্ক্রিপ্টে, txr_shellভেরিয়েবলটি পরবর্তীকালে হ'ল দুটি উদ্দেশ্যে ব্যবহৃত হয়: প্রথমত এটি স্ক্রিপ্টের আউটপুটে কোনও তথ্যমূলক বার্তার অংশ হিসাবে মুদ্রিত হয় Second দ্বিতীয়ত, এটি এর SHELLভেরিয়েবল হিসাবে ইনস্টল করা হয় Makefile, যাতে এটি makeব্যবহার করবে) রেসিপি কার্যকর করার জন্য খুব শেল।)

যে সিস্টেমে /bin/shড্যাশ রয়েছে সেখানে আপনি দেখতে পাচ্ছেন যে উপরের যুক্তিটি /bin/bashসেই সাথে স্ক্রিপ্টটি সন্ধান এবং পুনরায় সম্পাদন করবে ।

একটি সোলারিস 10 বাক্সে, /usr/xpg4/bin/shকোনও বাশ না পাওয়া গেলে কিল শুরু করবে।

প্রস্থানটি রক্ষণশীল শেল ডায়ালেক্টে testফাইলের অস্তিত্ব পরীক্ষার ${@+"$@"}জন্য এবং কিছু ভাঙা পুরাতন শাঁসকে সরবরাহ করার যুক্তিগুলি প্রসারিত করার কৌশল (যা কেবলমাত্র "$@"আমরা যদি পসিক্স কনফর্মিং শেলে থাকতাম) লেখা হয়েছিল।


xসঠিক উদ্ধৃতি ব্যবহার করা হলে কারওরই হ্যাকারির প্রয়োজন হবে না , যেহেতু সেই আইডিয়মকে আবদ্ধ করে দেওয়া পরিস্থিতিগুলি এখন একাধিক পরীক্ষার সাথে সম্মতিহীন পরীক্ষার প্রার্থনাগুলি -aবা সম্মিলনকে ঘিরে রেখেছে -o
চার্লস ডাফি

পছন্দ করেছেন test x$whateverযে আমি বার্নিশ মধ্যে একটি পেঁয়াজ মত সেখানে কেমন লাগে perpetrating করছি। যদি আমরা ভাঙা পুরানো শেলটি উদ্ধৃত করতে বিশ্বাস করতে না পারি তবে চূড়ান্ত ${@+"$@"}প্রচেষ্টা অর্থহীন।
কাজ

2

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

এক এবং একমাত্র সুবিধা শেল ভাষা এখনও সেসব নতুন বেশি ভাষায় রয়েছে কিছু কলিং নিজেই /bin/shকিছু প্রচরেই ইউনিক্স হতে উপস্থিত নিশ্চিত করা হয়। তবে, যে কোনও কিছু পসিক্স-কমপ্লায়েন্টও নাও হতে পারে; ইউনিক্স 95 (হ্যাঁ, ইউনিক্স 95, বিশ বছর আগে এবং গণনা) এর দাবি অনুযায়ী পরিবর্তিত হওয়ার পূর্বে অনেকগুলি মালিকানাধীন ইউনিক্সগুলি /bin/shডিফল্ট PATH- এ প্রয়োগ করা ভাষা এবং ইউটিলিটিগুলি হিমায়িত করে। সেখানে Unix95 একটি সেট হতে পারে, বা এমনকি POSIX.1-2001 যদি আপনি ভাগ্যবান, একটি ডিরেক্টরির মধ্যে সরঞ্জাম না ডিফল্ট পথে (যেমন ) কিন্তু তারা অস্তিত্ব নিশ্চিত করা হয় না।/usr/xpg4/bin

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

অতএব:

আপনি যদি এমন কিছু লিখছেন যা ইউনিক্স (যেমন একটি "কনফিগার করুন" স্ক্রিপ্ট) হিসাবে কাজগুলি সর্বত্র কাজ করতে হয় তবে আপনাকে ব্যবহার করা #! /bin/shদরকার এবং আপনাকে কোনও এক্সটেনশন ব্যবহার করার প্রয়োজন নেই। আজকাল আমি এই পরিস্থিতিতে POSIX.1-2-2001 মেনে চলতে সক্ষম শেল লিখব, তবে কেউ যদি মরিচা লোহা সমর্থন করার জন্য জিজ্ঞাসা করে আমি পজিক্সিজমগুলি প্যাচ করতে প্রস্তুত।

তবে আপনি যদি এমন কিছু লিখছেন না যা সর্বত্র কাজ করে চলেছে, তবে যে কোনও মুহূর্তে আপনি যে কোনও বাশিজমকে ব্যবহার করার প্রলোভন দেখিয়েছেন, তার পরিবর্তে পুরো বিষয়টিকে আরও ভাল স্ক্রিপ্টিং ভাষায় পুনরায় লিখতে হবে। আপনার ভবিষ্যত স্ব আপনাকে ধন্যবাদ জানাতে হবে।

(সুতরাং যখন হয় - স্মার্ট ট্যাব-সম্পূর্ণতে এবং অভিনব অনুরোধ জানানো প্রদান উদাঃ শুধুমাত্র ব্যাশ ইন্টারেক্টিভ পরিবেশ প্রসারিত করতে এটা ব্যাশ এক্সটেনশন ব্যবহার করার জন্য যথাযত প্রথম অর্ডার: কখনোই দ্বিতীয় অর্ডার।।)


অন্য দিন আমাকে এমন একটি স্ক্রিপ্ট লিখতে হয়েছিল যা এরকম কিছু করেছিল find ... -print0 |while IFS="" read -rd "" file; do ...; done |tar c --null -T -। বাশিজম ( read -d "") এবং জিএনইউ এক্সটেনশন ( find -print0, tar --null) ছাড়াই এটিকে সঠিকভাবে কাজ করা সম্ভব হবে না । পার্লের সেই লাইনটি পুনরায় বাস্তবায়ন করা আরও দীর্ঘ এবং clumsier হবে। বাশিজম এবং অন্যান্য নন-পসিক্স এক্সটেনশনগুলি ব্যবহার করার সময় এই ধরণের পরিস্থিতি হ'ল সঠিক জিনিস।
মিচাও

@michau এটা কি ঐ উপবৃত্ত যায় তার উপর নির্ভর করে আর একটি এক মাছ ধরার নৌকা হিসাবে যোগ্যতা নাও হতে পারে, কিন্তু আমি মনে করি আপনি গ্রহণ করছেন না "পুনর্লিখন সমগ্র জিনিস আক্ষরিক হিসাবে একটি ভাল স্ক্রিপ্টিং ভাষায়" হিসাবে আমি এটা বোঝানো। আমার perl -MFile::Find -e 'our @tarcmd = ("tar", "c"); find(sub { return unless ...; ...; push @tarcmd, $File::Find::name }, "."); exec @tarcmdউপায়টি দেখতে নোটিশের মতো এমন কিছু দেখায় যা কেবল আপনার কোনও বাশিজমের প্রয়োজন নেই, আপনার কোনও জিএনইউ টর এক্সটেনশনের প্রয়োজন নেই। (কমান্ড লাইনের দৈর্ঘ্য যদি উদ্বেগজনক হয় বা আপনি স্ক্যান এবং tar --null -T
ট্যারালটি

জিনিসটি হ'ল findআমার দৃশ্যে 50,000 এর বেশি ফাইলের নাম ফিরিয়ে দেওয়া হয়েছে, সুতরাং আপনার স্ক্রিপ্টটি যুক্তির দৈর্ঘ্যের সীমাতে আঘাত হানতে পারে। একটি সঠিক বাস্তবায়ন যা নন-পসিক্স এক্সটেনশনগুলি ব্যবহার করে না তার জন্য টার আউটপুটটি ক্রমবর্ধমানভাবে তৈরি করতে হবে বা পার্ক কোডটিতে আর্কাইভ :: টার :: স্ট্রিম ব্যবহার করতে হবে। অবশ্যই এটি করা যেতে পারে, তবে এই ক্ষেত্রে বাশ স্ক্রিপ্টটি লিখতে অনেক দ্রুত এবং কম বয়লারপ্লেট রয়েছে, এবং এর ফলে বাগগুলির জন্য কম স্থান রয়েছে।
মিচাও

BTW, আমি একটি দ্রুত এবং সংক্ষিপ্ত ভাবে ব্যাশ পরিবর্তে পার্ল ব্যবহার করতে পারে: find ... -print0 |perl -0ne '... print ...' |tar c --null -T -। তবে প্রশ্নগুলি হ'ল : আমি ব্যবহার করছি find -print0এবং tar --nullযাইহোক, তাই বাশিজমকে এড়িয়ে যাওয়ার কী দরকার read -d "", যা হুবহু একই ধরণের জিনিস (নাল বিভাজককে পরিচালনা করার জন্য একটি জিএনইউ এক্সটেনশন যা পার্লের বিপরীতে, কোনও দিন কোনও পসিক্স জিনিস হয়ে উঠতে পারে) )? 2) পার্ল কি আসলে বাশের চেয়ে বেশি বিস্তৃত? আমি সম্প্রতি ডকারের চিত্রগুলি ব্যবহার করছি এবং তাদের অনেকের কাছে ব্যাশ রয়েছে তবে পার্ল নেই। সেখানে প্রাচীন স্ক্রিপ্টগুলির চেয়ে নতুন স্ক্রিপ্টগুলি চালিত হওয়ার সম্ভাবনা বেশি।
মিচাউ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.