শেল স্ক্রিপ্টটি কার্যকর করার বিভিন্ন উপায়


44

একটি স্ক্রিপ্ট কার্যকর করার বিভিন্ন উপায় রয়েছে, আমি যেগুলি জানি সেগুলি হ'ল:

/path/to/script # using the path (absolute or relative)
. script        # using the . (dot)
source script   # using the `source` command

এর বেশি কি? তাদের মধ্যে পার্থক্য কি কি? এমন পরিস্থিতি আছে যে আমার অবশ্যই অন্যটি ব্যবহার করা উচিত নয়?


জেনে দুর্দান্ত, নীচে আপনার প্রশ্ন এবং উত্তরগুলির জন্য ধন্যবাদ, বিশেষত শনস। আমি এমন কিছু যুক্ত করতে চাই যা আমি কয়েকটি পরীক্ষা না চালানো পর্যন্ত আমার কাছে খুব স্পষ্ট ছিল না। উপরের দ্বিতীয় উপায়ে "/" অন্তর্ভুক্তি কমান্ডটিকে উপরের মোডে 1 নেবে। এটি, যখন "./myscript.sh" মোড 1 অনুসরণ করে, "। Myscript.sh" 2 টি মোডে লেগে থাকে You আপনি "পথটি (পরম বা আপেক্ষিক) ব্যবহার করে" উল্লেখ করেছিলেন, তবে কেবল এটি প্রকাশ করতে চেয়েছিলেন।
অরুণ 1

উত্তর:


32

আরেকটি উপায় হ'ল দোভাষীকে কল করা এবং স্ক্রিপ্টের দিকে পথটি পাঠানো:

/bin/sh /path/to/script

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

স্ক্রিপ্ট চালানোর অন্যান্য উপায়গুলি এটির নিজস্ব সাবশেলে চালাবে। স্ক্রিপ্টের ভেরিয়েবলগুলি সম্পূর্ণ হয়ে গেলে এখনও বেঁচে থাকে না। যদি স্ক্রিপ্ট ডিরেক্টরি পরিবর্তন করে, তবে এটি কলিং পরিবেশকে প্রভাবিত করে না।

/ পাথ / টু / স্ক্রিপ্ট এবং / বিন / শ স্ক্রিপ্ট কিছুটা আলাদা। সাধারণত, কোনও স্ক্রিপ্টের শুরুতে একটি "শেবাং" থাকে যা দেখতে এরকম দেখায়:

#! /bin/bash

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

উদাহরণস্বরূপ, পার্ল স্ক্রিপ্টস এবং রুবি স্ক্রিপ্টগুলি (যথাক্রমে) দিয়ে শুরু হয়:

#! /bin/perl

এবং

#! /bin/ruby

আপনি যদি এই স্ক্রিপ্টগুলির মধ্যে একটি চালনা করে চালিয়ে যান /bin/sh scriptতবে সেগুলি মোটেই কার্যকর হবে না।

উবুন্টু আসলে ব্যাশ শেলটি ব্যবহার করে না, তবে ড্যাশ নামে পরিচিত একটি খুব অনুরূপ। ব্যাশ প্রয়োজন এমন স্ক্রিপ্টগুলি যখন ডেকে ডাকা হয় তখন কিছুটা ভুল কাজ করতে পারে /bin/sh scriptকারণ আপনি ড্যাশ ইন্টারপ্রেটার ব্যবহার করে কেবল ব্যাশ স্ক্রিপ্ট কল করেছেন।

সরাসরি স্ক্রিপ্টটি কল করা এবং দোভাষীকে স্ক্রিপ্টের পথটি প্রেরণের মধ্যে আরেকটি ছোট পার্থক্য হ'ল স্ক্রিপ্টটি সরাসরি চালনার জন্য নির্বাহযোগ্য হিসাবে চিহ্নিত করা উচিত, তবে দোভাষীকে পথ দিয়ে চালানো নয়।

আরেকটি ছোটখাটো প্রকরণ: আপনি স্ক্রিপ্টটি ওয়াল দিয়ে কার্যকর করতে এই যে কোনও উপায়ে উপসর্গ করতে পারেন, সুতরাং আপনি তা করতে পারেন

eval sh script
eval script
eval . script

ইত্যাদি। এটি আসলে কোনও পরিবর্তন করে না, তবে আমি ভেবেছিলাম এটি সম্পূর্ণতার জন্য অন্তর্ভুক্ত করব।


6
"উবুন্টু আসলে ব্যাশ শেল ব্যবহার করে না" বলা অসম্পূর্ণ এবং প্রযুক্তিগতভাবে ভুল। উবুন্টু করে ব্যাশ শেল ব্যবহার, পয়েন্ট যে shসাথে সঙ্গতিপূর্ণ dash, কিন্তু না করতে bash
ফাহিম মিঠা

@ শ্যাওন ফার্স্ট প্যারাগুলিতে আপনি লিখেছেন "এটি স্ক্রিপ্টটি যথাযথভাবে সম্পাদন করে (যেন আপনি ঠিক সেখানে স্ক্রিপ্টটি অনুলিপি করে আটকে দিয়েছেন)। এর অর্থ হ'ল স্ক্রিপ্টের কোনও ফাংশন এবং স্থানীয় কোনও অক্ষর নেই" " এখানে দ্বিতীয় লাইনের অর্থ কী? আপনি দয়া করে ব্যাখ্যা করতে পারেন।
গিক

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

@ শনজ.গফ স্পষ্টতার জন্য ধন্যবাদ। +1 টি।
গীক

প্লট-টুইস্ট: বোর্ন শেল (শে) কেবল বিন্দু গ্রহণ করে - উত্স নয় কারণ এটি ব্যাশ-বিল্টিন। pubs.opengroup.org/onlinepubs/9699919799/utilities/… তাই আমি বলি যে সবচেয়ে বহনযোগ্য উপায় একটি বিন্দু।
dezza

9

বেশিরভাগ লোকেরা স্ক্রিপ্টগুলিতে নিম্নলিখিত ডিবাগিং পতাকাগুলি যুক্ত করে শেল স্ক্রিপ্টগুলি ডিবাগ করে :

set -x     # Print command traces before executing command.
set -v     # Prints shell input lines as they are read.
set -xv    # Or do both

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

এগুলি করার পরিবর্তে, আপনি কমান্ডলাইনে ডিবাগিং পতাকাগুলি সেট করতে পারেন:

$ bash -x ~/bin/ducks
+ du -cks -x dir1 dir2 dir3 file1 file2 file3
+ sort -n
+ tail .ducks
123 etc
424 bin
796 total



$ sh -xv ~/bin/ducks  
#!/usr/bin/env bash

# Find the disk hog
# Borrowed from http://oreilly.com/pub/h/15
...
...

2
সম্পর্কিত টিপ: আমি emulate sh 2>/dev/nullআমার শেল স্ক্রিপ্টগুলির শীর্ষে রাখার অভ্যাসটি পেয়েছি। যখন zsh দিয়ে চালানো হয়, এটি এটি পসিক্স সামঞ্জস্যপূর্ণ মোডে রাখে। অন্যান্য শাঁস দিয়ে চালানোর সময়, লাইনের কোনও প্রভাব নেই। তারপরে আমি স্ক্রিপ্টটি দিয়ে চালাতে পারি zsh -x /path/to/script। আমি এখানে zsh পছন্দ করি কারণ এটি বাশ বা ksh এর চেয়ে ভাল ট্রেস সরবরাহ করে।
গিলস 'অসন্তুষ্ট হওয়া বন্ধ করুন'

7

শন জে গফ প্রচুর ভাল পয়েন্ট তৈরি করেছিলেন তবে পুরো গল্পটি অন্তর্ভুক্ত করেননি:

উবুন্টু আসলে ব্যাশ শেলটি ব্যবহার করে না, তবে ড্যাশ নামে পরিচিত একটি খুব অনুরূপ। স্ক্রিপ্টগুলি যখন /bin/shস্ক্রিপ্টগুলি দ্বারা ডাকা হয় তখন স্ক্রিপ্টগুলি কিছুটা ভুল কাজ করতে পারে কারণ আপনি ড্যাশ ইন্টারপ্রেটার ব্যবহার করে বাশ স্ক্রিপ্টটি ডেকেছিলেন।

প্রচুর সিস্টেম স্ক্রিপ্টগুলিতে (যেমন init.d তে, ইন / ইত্যাদি ইত্যাদি) একটি শেবাং থাকে #!/bin/shতবে /bin/shএটি আসলে অন্য শেলের একটি প্রতীকী যোগসূত্র। পূর্ববর্তী সময়ে /bin/bash, আজকাল /bin/dash। কিন্তু যখন তাদের একজনকে ডাকা হয় /bin/sh, তারা অন্যরকম আচরণ করে, অর্থাত্ তারা পসিক্স-সামঞ্জস্যতা মোডে লেগে থাকে।

তারা কিভাবে এই কাজ করে? ঠিক আছে, তারা কীভাবে আহ্বান জানানো হয়েছিল তা খতিয়ে দেখেন।

একটি শেলসক্রিপ্ট নিজেই পরীক্ষা করতে পারে যে এটি কীভাবে আহ্বান করা হয়েছিল এবং তার উপর নির্ভর করে বিভিন্ন কাজ করতে পারে? হ্যাঁ এটা পারি. সুতরাং আপনি যেভাবে এটি চালনা করেছেন তা সর্বদা বিভিন্ন ফলাফলের দিকে নিয়ে যেতে পারে তবে অবশ্যই আপনাকে বিরক্ত করার জন্য এটি খুব কমই করা হয়ে থাকে। :)

থাম্বের নিয়ম হিসাবে: আপনি যদি বাশের মতো কোনও নির্দিষ্ট শেল শিখছেন, এবং বাশ টিউটোরিয়াল থেকে কমান্ড লিখছেন, #!/bin/bashশিরোনামে রাখুন, #!/bin/shঅন্যথায় উল্লেখ করা ব্যতীত not অন্যথায় আপনার আদেশগুলি ব্যর্থ হতে পারে। এবং যদি আপনি লেখেননি একটি স্ক্রিপ্ট নিজেকে, তা সরাসরি ডাকা ( ./foo.sh, bar/foo.shপরিবর্তে একটি শেল মনন এর () sh foo.sh, sh bar/foo.sh)। শেবাংয়ের ডান শেলটি শুরু করা উচিত।

এবং এখানে আরও দুটি ধরণের প্রার্থনা রয়েছে:

cat foo.sh | dash
dash < foo.sh

5

.এবং sourceএর সমতুল্য যে তারা কোনও সাব-প্রসেস স্প্যান করে না তবে বর্তমান শেলটিতে কমান্ড কার্যকর করে। স্ক্রিপ্টটি পরিবেশের ভেরিয়েবল সেট করে বা বর্তমান কার্যক্ষম ডিরেক্টরি পরিবর্তন করে এটি গুরুত্বপূর্ণ।

পথটি ব্যবহার করা বা এটি দেওয়া /bin/shএকটি নতুন প্রক্রিয়া তৈরি করে যাতে আদেশগুলি কার্যকর করা হয়।


2
sh script
bash script

আরও কিছু থাকলে আমি চিন্তা করছি ...

.এবং sourceএকই। মৃত্যুদন্ড কার্যকর করার পরে পরিবেশের যে কোনও পরিবর্তন scriptরাখা হবে। সাধারণত এটি ব্যাশ লাইব্রেরি উত্স হিসাবে ব্যবহৃত হত, তাই লাইব্রেরিটি বিভিন্ন স্ক্রিপ্টগুলিতে পুনরায় ব্যবহার করা যেতে পারে।

এছাড়াও এটি বর্তমান ডিরেক্টরি রাখার একটি ভাল উপায়। আপনি যদি স্ক্রিপ্টে ডিরেক্টরি পরিবর্তন করেন তবে এটি আপনি যে স্ক্রিপ্টটি চালান সেই শেলটিতে এটি প্রয়োগ করা হবে না। আপনি যদি এটি চালানোর জন্য এটি উত্স করেন তবে স্ক্রিপ্টটি প্রস্থান করার পরে, বর্তমান ডিরেক্টরিটি রাখা হবে।


2
.কেবল শ / বাশ এবং সম্পর্কিত শেলগুলিতে কাজ করে। sourceসিএসএস এবং সম্পর্কিত শেলগুলিতেও কাজ করে।
কিথবি


1
. ./filename
# ( dot space dot slash filename )

ডিরেক্টরি যখন পথে না থাকে তখন বর্তমান শেলটিতে স্ক্রিপ্টটি চালায়।


1

। এবং উত্স কমপক্ষে zsh এ কিছুটা আলাদা (কারণ আমি এটি ব্যবহার করি) কারণ

source file

ওয়ার্কস, যখন

. file

না, এটি প্রয়োজন

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