বাশ-এ প্রোগ্রামিংয়ের "কলব্যাক" ধারণাটি কি বিদ্যমান?


21

প্রোগ্রামিং সম্পর্কে যখন কয়েকবার পড়ি তখন আমি "কলব্যাক" ধারণাটি পেয়েছিলাম।

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

বাশ-এ প্রোগ্রামিংয়ের "কলব্যাক" ধারণাটি কি বিদ্যমান? যদি তা হয় তবে দয়া করে একটি ছোট, সাধারণ, বাশ উদাহরণ সহ উত্তর দিন।


2
"কলব্যাক" একটি বাস্তব ধারণা বা এটি "প্রথম শ্রেণির ফাংশন"?
সিড্রিক এইচ।

আপনি declarative.bashআকর্ষণীয় সন্ধান করতে পারেন , একটি ফ্রেমওয়ার্ক হিসাবে যা কোনও নির্দিষ্ট মান প্রয়োজন হলে ডাকা হওয়ার জন্য কনফিগার করা ফাংশনগুলিকে স্পষ্টভাবে উপার্জন করে।
চার্লস ডাফি

আরেকটি প্রাসঙ্গিক কাঠামো: বাশআপ / ইভেন্ট । এর ডকুমেন্টেশনে ক্যালব্যাক ব্যবহারের অনেকগুলি সাধারণ ডেমো যেমন বৈধকরণ, লকআপস ইত্যাদির জন্য রয়েছে
পিজে এবি

1
@CedricH। আপনার পক্ষে ভোট দিয়েছেন "" কলব্যাক "একটি আসল ধারণা বা এটি" প্রথম শ্রেণির ফাংশন "?" অন্য প্রশ্ন হিসাবে জিজ্ঞাসা করা ভাল প্রশ্ন?
প্রোসোডি-গ্যাব Vereable প্রসঙ্গ 0

আমি "একটি প্রদত্ত ইভেন্টের ট্রিগার হওয়ার পরে ফিরে আসা একটি ফাংশন" এর অর্থ কলব্যাক বুঝতে পারি। এটা কি ঠিক?
জনডোইয়া

উত্তর:


44

সাধারণ অত্যাবশ্যক প্রোগ্রামিংয়ে , আপনি নির্দেশের অনুক্রম লিখেন এবং সেগুলি একের পর এক নির্বাহ করা হয়, সুস্পষ্ট নিয়ন্ত্রণ প্রবাহের মাধ্যমে। উদাহরণ স্বরূপ:

if [ -f file1 ]; then   # If file1 exists ...
    cp file1 file2      # ... create file2 as a copy of a file1
fi

প্রভৃতি

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

কলব্যাকগুলি কীভাবে প্রবাহকে পরিবর্তন করে

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

#!/bin/bash

scripttmp=$(mktemp -d)           # Create a temporary directory (these will usually be created under /tmp or /var/tmp/)

cleanup() {                      # Declare a cleanup function
    rm -rf "${scripttmp}"        # ... which deletes the temporary directory we just created
}

trap cleanup EXIT                # Ask Bash to call cleanup on exit

আপনি যদি নিজে চেষ্টা করে দেখতে চান তবে উপরের ফাইলটিকে একটি ফাইলে সংরক্ষণ করুন, বলুন cleanUpOnExit.sh, এটি কার্যকর করুন এবং চালনা করুন:

chmod 755 cleanUpOnExit.sh
./cleanUpOnExit.sh

আমার কোড এখানে স্পষ্টভাবে cleanupফাংশন কল করে না ; এটি বাশকে কখন ফোন করবে তা বলছে trap cleanup EXIT, অর্থাত্ "প্রিয় বাশ, cleanupআপনি প্রস্থান করার সময় দয়া করে কমান্ডটি চালান " (এবং cleanupএটি আমি আগে সংজ্ঞায়িত একটি ফাংশন বলে মনে করি, তবে এটি বাশ বুঝতে পারে এমন কিছু হতে পারে)। বাশ এটি সমস্ত অ-মারাত্মক সংকেত, প্রস্থান, কমান্ড ব্যর্থতা এবং সাধারণ ডিবাগিংয়ের জন্য সমর্থন করে (আপনি একটি কলব্যাক নির্দিষ্ট করতে পারবেন যা প্রতিটি কমান্ডের আগে চলমান)। এখানে কলব্যাকটি হ'ল cleanupফাংশন, যা শশটি প্রস্থান করার ঠিক আগে বাশ দ্বারা "ফিরে" বলে।

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

#!/bin/bash

doonall() {
    command="$1"
    shift
    for arg; do
        "${command}" "${arg}"
    done
}

backup() {
    mkdir -p ~/backup
    cp "$1" ~/backup
}

doonall backup "$@"

(আমি জানি এটি কিছুটা অকেজো কারণ যেহেতু cpএকাধিক ফাইল ডিল করতে পারে এটি কেবল উদাহরণের জন্য))

এখানে আমরা একটি ফাংশন তৈরি করি doonall, যা প্যারামিটার হিসাবে দেওয়া অন্য একটি কমান্ড নেয় এবং এটি এর বাকি পরামিতিগুলিতে প্রয়োগ করে; তারপরে আমরা backupস্ক্রিপ্টকে দেওয়া সমস্ত পরামিতিগুলিতে ফাংশনটি কল করতে এটি ব্যবহার করি । ফলাফলটি এমন একটি স্ক্রিপ্ট যা এর সমস্ত যুক্তিগুলি একে একে ব্যাকআপ ডিরেক্টরিতে অনুলিপি করে।

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

এক্ষেত্রে কলব্যাক হ'ল backupফাংশন, যা আমরা এর doonallপ্রতিটি অন্যান্য আর্গুমেন্টের "কল ব্যাক" করতে বলি - আমরা doonallআচরণ (এর প্রথম যুক্তি) পাশাপাশি ডেটা (বাকী যুক্তি) সরবরাহ করি।

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


25

প্রথমে এটি লক্ষ করা গুরুত্বপূর্ণ যে কোনও ফাংশনকে কলব্যাক ফাংশন কী করে তা কীভাবে এটি ব্যবহৃত হয় তা নয় not একটি কলব্যাক হয় যখন আপনি যে কোডটি লেখেন সেই কোড থেকে কল করা হয় যা আপনি লেখেন নি। আপনি যখন কোনও বিশেষ ঘটনা ঘটে তখন আপনাকে সিস্টেমে ফোন করতে বলছে।

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

কলব্যাকের আরেকটি উদাহরণ হ'ল কমান্ডের -execক্রিয়া findfindকমান্ডের কাজটি হ'ল ডিরেক্টরিগুলি পুনরাবৃত্তভাবে অনুসরণ করতে এবং প্রতিটি ফাইলকে পরিবর্তে প্রক্রিয়াজাত করা। ডিফল্টরূপে, প্রসেসিং হ'ল ফাইলের নাম (অন্তর্নিহিত -print) মুদ্রণ করা হয় , তবে -execপ্রসেসিংয়ের সাথে আপনি নির্দিষ্ট করা একটি আদেশ চালানো হয়। এটি একটি কলব্যাকের সংজ্ঞা ফিট করে, যদিও কলব্যাকগুলি যেতে পারে, কলব্যাকটি পৃথক প্রক্রিয়াতে চলার পরে এটি খুব নমনীয় নয়।

যদি আপনি কোনও সন্ধানের মতো ফাংশনটি প্রয়োগ করেন তবে আপনি প্রতিটি ফাইলে কল করার জন্য কলব্যাক ফাংশনটি ব্যবহার করতে পারেন। এখানে একটি অতি-সরলযুক্ত সন্ধানের মতো ফাংশন রয়েছে যা একটি ফাংশনের নাম (বা বহিরাগত কমান্ড নাম) যুক্তি হিসাবে গ্রহণ করে এবং বর্তমান ডিরেক্টরি এবং এর উপ-ডিরেক্টরিগুলির সমস্ত নিয়মিত ফাইলগুলিতে এটি কল করে। ফাংশনটি কলব্যাক হিসাবে ব্যবহৃত হয় যা প্রতিবার call_on_regular_filesএকটি নিয়মিত ফাইল খুঁজে পায় called

shopt -s globstar
call_on_regular_files () {
  declare callback="$1"
  declare file
  for file in **/*; do
    if [[ -f $file ]]; then
      "$callback" "$file"
    fi
  done
}

কিছু অন্যান্য পরিবেশের মতো শেল প্রোগ্রামিংয়ে কলব্যাকগুলি সাধারণ হয় না কারণ শেলগুলি প্রাথমিকভাবে সাধারণ প্রোগ্রামগুলির জন্য তৈরি করা হয়। কলব্যাকগুলি এমন পরিবেশে বেশি দেখা যায় যেখানে ডেটা এবং কন্ট্রোল ফ্লো কোডের যে অংশগুলি স্বতন্ত্রভাবে লিখিত এবং বিতরণ করা হয় সেগুলির মধ্যে পিছনে পিছনে সরে যাওয়ার সম্ভাবনা রয়েছে: বেস সিস্টেম, বিভিন্ন গ্রন্থাগার, অ্যাপ্লিকেশন কোড।


1
বিশেষভাবে সুন্দরভাবে ব্যাখ্যা করা হয়েছে
রোয়াইমা

1
@ জোহানডোইয়া আমার ধারণা এই ধারণাটি হ'ল এটি অতি-সরল যা এটি কোনও ফাংশন নয় যা আপনি সত্যিই লিখতে চান। কিন্তু সম্ভবত একটি এমনকি সহজ উদাহরণ কলব্যাক চালানোর জন্য একটি হার্ড কোডেড তালিকা সঙ্গে কিছু হবে: foreach_server() { declare callback="$1"; declare server; for server in 192.168.0.1 192.168.0.2 192.168.0.3; do "$callback" "$server"; done; }যা আপনি হিসাবে চালানো পারে foreach_server echo, foreach_server nslookupইত্যাদি declare callback="$1"সম্পর্কে সহজ যদিও যেমন পেতে পারেন হিসাবে: কলব্যাক কোথাও পাস করা হয়েছে, বা এটি একটি কলব্যাক নয়।
আইএমএসওপি

4
'একটি কলব্যাক হয় যখন আপনি যে কোডটি লেখেন সেই কোড থেকে কল করা হয় যা আপনি লেখেন নি' ' সহজভাবে ভুল। আপনি এমন কিছু লিখতে পারেন যা কিছু অ-ব্লক করা অ্যাসিঙ্ক কাজ করে, এবং এটি একটি কলব্যাক দিয়ে চালায় এটি শেষ হলে এটি চলবে। কোডটি কে লিখেছিল তার সাথে কিছুই সম্পর্কিত নয়
মাইকম্যাকানা

5
@ মিকেম্যাকানা অবশ্যই এটি একই ব্যক্তি কোডটির দুটি অংশ লিখেছিলেন। তবে এটি সাধারণ ঘটনা নয়। আমি একটি ধারণার বেসিকগুলি ব্যাখ্যা করছি, কোনও আনুষ্ঠানিক সংজ্ঞা দিচ্ছি না। যদি আপনি সমস্ত কোণার কেস ব্যাখ্যা করেন তবে প্রাথমিক বিষয়গুলি জানানো কঠিন।
গিলস

1
এটা শুনে আনন্দিত. আমি একমত নই যে কলব্যাক এবং কলব্যাক ব্যবহার করে এমন কোড দুটিই লোক লিখেছেন বা এটি সাধারণ নয় বা একটি প্রান্তের কেস এবং এই বিভ্রান্তির কারণে যে এই উত্তরটি মৌলিক বিষয়গুলি জানায়।
মাইকমেকানা

7

"কলব্যাকস" কেবল অন্যান্য ফাংশনগুলির আর্গুমেন্ট হিসাবে গৃহীত ফাংশন।

শেল স্তরে, এর সহজ অর্থ হ'ল স্ক্রিপ্ট / ফাংশন / কমান্ডগুলি অন্যান্য স্ক্রিপ্ট / ফাংশন / কমান্ডের আর্গুমেন্ট হিসাবে পাস হয়।

এখন, একটি সাধারণ উদাহরণের জন্য, নিম্নলিখিত স্ক্রিপ্টটি বিবেচনা করুন:

$ cat ~/w/bin/x
#! /bin/bash
cmd=$1; shift
case $1 in *%*) flt=${1//\%/\'%s\'};; *) flt="$1 '%s'";; esac; shift
q="'\\''"; f=${flt//\\/'\\'}; p=`printf "<($f) " "${@//\'/$q}"`
eval "$cmd" "$p"

সংক্ষিপ্তসার হচ্ছে

x command filter [file ...]

filterপ্রতিটি fileযুক্তিতে প্রযোজ্য হবে , তারপরে commandফিল্টারগুলির আউটপুটগুলির সাথে আর্গুমেন্ট হিসাবে কল করুন ।

এই ক্ষেত্রে:

x diff zcat a.gz b.bz   # diff gzipped files
x diff3 zcat a.gz b.gz c.gz   # same with three-way diff
x diff hd a b  # hex diff of binary files
x diff 'zcat % | sort -u' a.gz b.gz  # first uncompress the files, then sort+uniq them, then compare them
x 'comm -12' sort a b  # find common lines in unsorted files

এটি আপনি লিস্পে যা করতে পারেন তার খুব কাছে (কেবল মজা করা ;-))

কিছু লোক "কলব্যাক" শব্দটিকে "ইভেন্ট হ্যান্ডলার" এবং / অথবা "ক্লোজার" (ফাংশন + ডেটা / এনভায়রনমেন্ট টুপল) সীমাবদ্ধ করার জন্য জোর দিয়ে থাকে; এটি কোনওভাবেই সাধারণভাবে গৃহীত অর্থ নয়। এই সংকীর্ণ ইন্দ্রিয়গুলিতে শেলটিতে "কলব্যাকস" বেশি ব্যবহার না করার একটি কারণ হ'ল পাইপ + সমান্তরালতা + গতিশীল প্রোগ্রামিং ক্ষমতা এত বেশি শক্তিশালী এবং আপনি ইতিমধ্যে পারফর্মেন্সের ক্ষেত্রে তাদের জন্য অর্থ প্রদান করছেন, এমনকি যদি আপনি শেলটি perlবা এর ক্লঙ্কি সংস্করণ হিসাবে ব্যবহার করার চেষ্টা করুন python


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

1
@Joe এটা মাত্র দুটি ইনপুট ফাইল এবং কোন সঙ্গে কাজ করার জন্য ওকে যদি %ফিল্টারের ক্ষেপক, গোটা ব্যাপারটাই কমে যেতে পারে: cmd=$1; shift; flt=$1; shift; $cmd <($flt "$1") <($flt "$2")। তবে এটি অনেক কম দরকারী এবং চিত্রিত ইমো।
ম্যাসভি

1
বা আরও ভাল$1 <($2 "$3") <($2 "$4")
ম্যাসভি

+1 ধন্যবাদ আপনার মন্তব্যগুলি, প্লাস এটিকে ঘুরে দেখার এবং কোডটি কিছু সময়ের জন্য খেলে আমার কাছে তা স্পষ্ট করে দিয়েছিল। আমি একটি নতুন শব্দ "স্ট্রিং ইন্টারপোলেশন" শিখেছি, যার জন্য আমি চিরকাল ব্যবহার করছি।
জো

4

ধরনের।

ব্যাশে কলব্যাক প্রয়োগের একটি সহজ উপায় হ'ল একটি প্রোগ্রামের নামটিকে প্যারামিটার হিসাবে গ্রহণ করা, যা "কলব্যাক ফাংশন" হিসাবে কাজ করে।

# This is script worker.sh accepts a callback in $1
cb="$1"
....
# Execute the call back, passing 3 parameters
$cb foo bar baz

এটি এভাবে ব্যবহার করা হবে:

# Invokes mycb.sh as a callback
worker.sh mycb.sh

অবশ্যই আপনার বাশে ক্লোজার নেই। সুতরাং, কলব্যাক ফাংশনটিতে কলার দিকে ভেরিয়েবলের অ্যাক্সেস নেই। আপনি যাইহোক, পরিবেশের ভেরিয়েবলগুলিতে কলব্যাকের প্রয়োজনীয় ডেটা সঞ্চয় করতে পারেন। কলব্যাক থেকে ইনভোকার স্ক্রিপ্টে ফিরে তথ্য পাঠানো জটিল trick ডেটা একটি ফাইলে রাখা যেতে পারে।

যদি আপনার নকশাটি একক প্রক্রিয়াতে সবকিছু হ্যান্ডল করার অনুমতি দেয় তবে আপনি কলব্যাকের জন্য একটি শেল ফাংশন ব্যবহার করতে পারেন এবং এই ক্ষেত্রে কলব্যাক ফাংশনটি অবশ্যই চালকের পক্ষে চলকগুলিতে অ্যাক্সেস করতে পারে।


3

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

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

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

আমি এই উত্তরটি একটি ফাংশনটিকে অন্য ফাংশনে পাস করার আরও একটি পদ্ধতি দিয়ে পূর্ণ করব, যা স্পষ্টভাবে বাশ-তে উপস্থিত নেই। এটি নাম দ্বারা নয়, ঠিকানায় এটি পাস করছে। এটি পার্লের মধ্যে পাওয়া যাবে, উদাহরণস্বরূপ। বাশ ফাংশন বা ভেরিয়েবলের জন্য এইভাবে অফার করে। তবে, আপনি যেমন উল্লেখ করেছেন, আপনি যেমন বাশের সাথে একটি উদাহরণ হিসাবে কেবল একটি বিস্তৃত চিত্র রাখতে চান, তবে আপনার জানা উচিত, ফাংশন কোডটি মেমরির কোথাও থাকতে পারে এবং সেই কোডটি সেই মেমরির অবস্থান দ্বারা অ্যাক্সেস করা হতে পারে, যা এর ঠিকানা বলা।


2

ব্যাশে কলব্যাকের সহজ উদাহরণগুলির মধ্যে একটি হ'ল প্রচুর লোকের সাথে পরিচিত তবে তারা বুঝতে পারে না যে তারা আসলে কোন ডিজাইনের প্যাটার্নটি ব্যবহার করছে:

ক্রন

ক্রোন আপনাকে একটি এক্সিকিউটেবল (বাইনারি বা স্ক্রিপ্ট) নির্দিষ্ট করার অনুমতি দেয় যা কিছু শর্ত পূরণ করার সময় ক্রোন প্রোগ্রামটি আবার কল করবে (সময় নির্দিষ্টকরণ)

বলুন আপনার কাছে একটি স্ক্রিপ্ট কল আছে doEveryDay.sh। স্ক্রিপ্টটি লেখার নন-কলব্যাক উপায়টি হ'ল:

#! /bin/bash
while true; do
    doSomething
    sleep $TWENTY_FOUR_HOURS
done

এটি লেখার কলব্যাক উপায়টি হ'ল:

#! /bin/bash
doSomething

তারপরে ক্রন্টব এ আপনি এমন কিছু সেট করে রেখেছিলেন

0 0 * * *     doEveryDay.sh

তারপরে আপনাকে ইভেন্টটি ট্রিগার হওয়ার জন্য অপেক্ষা করার জন্য কোডটি লেখার প্রয়োজন হবে না তবে পরিবর্তে cronআপনার কোডটি কল করার জন্য নির্ভর করুন ।


এখন, আপনি বিবেচনা করুন কীভাবে আপনি এই কোডটি ব্যাশে লিখবেন।

আপনি কীভাবে বাশে আরেকটি স্ক্রিপ্ট / ফাংশন সম্পাদন করবেন?

আসুন একটি ফাংশন লিখি:

function every24hours () {
    CALLBACK=$1 ;# assume the only argument passed is
                 # something we can "call"/execute
    while true; do
        $CALLBACK ;# simply call the callback
        sleep $TWENTY_FOUR_HOURS
    done
}

এখন আপনি একটি ফাংশন তৈরি করেছেন যা কলব্যাক গ্রহণ করে। আপনি এটিকে সহজভাবে এটি কল করতে পারেন:

# "ping" google website every day
every24hours 'curl google.com'

অবশ্যই, প্রতি 24 ঘন্টা সময় ফাংশনটি আর ফিরে আসে না। বাশ কিছুটা স্বতন্ত্র যে আমরা খুব সহজেই এটিকে অবিচ্ছিন্ন করতে পারি এবং যুক্ত করে একটি প্রক্রিয়া তৈরি করতে পারি &:

every24hours 'curl google.com' &

আপনি যদি এটি কোনও ক্রিয়া হিসাবে না চান তবে পরিবর্তে আপনি এটি স্ক্রিপ্ট হিসাবে এটি করতে পারেন:

#every24hours.sh
CALLBACK=$1 ;# assume the only argument passed is
               # something we can "call"/execute
while true; do
    $CALLBACK ;# simply call the callback
    sleep $TWENTY_FOUR_HOURS
done

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

CALLBACK_SCRIPT=$3 ;# or some other 
                    # argument to 
                    # function/script

এবং কলব্যাক কল করা সহজ:

$SOME_CALLBACK_FUNCTION_OR_SCRIPT

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


কলব্যাক গ্রহণযোগ্য প্রোগ্রাম / স্ক্রিপ্টগুলির অন্যান্য উদাহরণগুলির মধ্যে রয়েছে watchএবং find( -execপ্যারামিটারের সাথে ব্যবহার করার সময় )
slebetman

0

কলব্যাক হ'ল এমন একটি ফাংশন যা কোনও ইভেন্ট ঘটে। এর সাথে bash, স্থানটিতে একমাত্র ইভেন্ট হ্যান্ডলিং প্রক্রিয়া সম্পর্কিত সংকেত, শেল প্রস্থান এবং শেল ত্রুটির ঘটনা, ডিবাগ ইভেন্ট এবং ফাংশন / সর্স স্ক্রিপ্টগুলি রিটার্ন ইভেন্টগুলির সাথে সম্পর্কিত।

এখানে একটি অকেজো কিন্তু সহজ কলব্যাকের লিভারেজিং সিগন্যাল ট্র্যাপগুলির একটি উদাহরণ।

প্রথমে কলব্যাক প্রয়োগকারী স্ক্রিপ্ট তৈরি করুন:

#!/bin/bash

myCallback() {
    echo "I've been called at $(date +%Y%m%dT%H%M%S)"
}

# Set the handler
trap myCallback SIGUSR1

# Main loop. Does nothing useful, essentially waits
while true; do
    read foo
done

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

/ ./callback- উদাহরণ

এবং অন্য একটিতে, USR1শেল প্রক্রিয়াতে সংকেত প্রেরণ করুন ।

$ pkill -USR1 callback-example

প্রেরিত প্রতিটি সিগন্যালের প্রথম টার্মিনালে এইগুলির মতো লাইনের প্রদর্শনকে ট্রিগার করা উচিত:

I've been called at 20180925T003515
I've been called at 20180925T003517

ksh93শেল হিসাবে অনেকগুলি বৈশিষ্ট্য যা bashপরে গৃহীত হয়েছিল তা প্রয়োগ করে এটি "শৃঙ্খলা ফাংশন" বলে calls bashশেল ভেরিয়েবল পরিবর্তন বা রেফারেন্স করা (অর্থাত্ পঠিত) হয় যখন এই ফাংশনগুলি, সাথে উপলব্ধ নয় called এটি আরও আকর্ষণীয় ইভেন্ট চালিত অ্যাপ্লিকেশনগুলির পথ উন্মুক্ত করে।

উদাহরণস্বরূপ, এই বৈশিষ্ট্যটি গ্রাফিক উইজেটগুলিতে X11 / Xt / মোটিফ শৈলীর কলব্যাকগুলিকে kshগ্রাফিক এক্সটেনশনগুলির অন্তর্ভুক্ত থাকা পুরানো সংস্করণে প্রয়োগ করার অনুমতি দিয়েছে dtkshDksh ম্যানুয়াল দেখুন ।

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