কল ফাংশন নীচে ঘোষণা করা


15

নীচে ব্যাশে ঘোষিত কোনও ফাংশন কল করা কি সম্ভব?

উদাহরণ

if [ "$input" = "yes" ]; then
    YES_FUNCTION
elif [ "$input" = "no" ]; then
    NO_FUNCTION
else
    exit 0;
fi

YES_FUNCTION()
{
  .....
  .....
}

NO_FUNCTION()
{
  .....
  .....
}

উত্তর:


37

অন্যরা যেমন বলেছে, আপনি এটি করতে পারবেন না।

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

যেমন

#!/bin/sh

main() {
    if [ "$1" = yes ]; then
        do_task_this
    else
        do_task_that
    fi
}

do_task_this() {
    ...
} 
do_task_that() {
    ...
} 

main "$@"; exit

আমরা যখন mainফাইলের শেষে কল করি তখন সমস্ত ফাংশন ইতিমধ্যে সংজ্ঞায়িত হয়। ফাংশনে দৃশ্যমানভাবে স্ক্রিপ্টের কমান্ড লাইন আর্গুমেন্টগুলি তৈরি করার জন্য স্পষ্টভাবে প্রেরণ "$@"করা mainপ্রয়োজন।

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


@ আইক্কাচু ভাবেন এটি কাজ করা উচিত .. আমাকে পরীক্ষা করতে দিন।
এমএসপি 9011

8
বাশ স্ক্রিপ্টগুলির সাহায্যে আমি প্রায়শই [[ ${BASH_SOURCE[0]} = "$0" ]] && Main "$@"মূল ফাংশনটি কল করতে ব্যবহার করি যাতে আমি এটি Mainসম্পাদন না করেই অন্য স্ক্রিপ্টে উত্স করতে পারি । তারপরে আমি হয় ফাংশনগুলি পুনরায় ব্যবহার করতে পারি বা সেগুলি পরীক্ষা করে পরীক্ষা লিখতে পারি।
ব্ল্যাকজ্যাক

11
রয়ে main "$@"; exit(সঙ্গে exitযেমন একই লাইনে main) হিসাবে ফাইল বিরুদ্ধে রক্ষাকবচ যখন এটি ব্যাখ্যা করা হয় পরিবর্তিত হচ্ছে এছাড়াও দরকারী।
স্টাফেন চেজেলাস

2
@ জোল, যা পড়ে তা আর পড়তে হবে না এবং শেলটি চালানোর আগে একটি লুপের পুরো পাঠটি পড়ার এবং বিশ্লেষণ করতে হবে তবে লুপটি ফেরার পরে এটি ফাইলের বাকী অংশ থেকে পড়া চালিয়ে যাবে বর্তমান অবস্থান (এবং যদি ফাইলটি সংশোধন করা হয়েছে তবে এটি জিনিসগুলি স্ক্রু করবে)। যদি সমস্ত কিছু কার্যক্রমে থাকে তবে শেলটিকে কিছু করার আগে (সেই ফাংশনগুলি সংজ্ঞায়িত করা ব্যতীত) সমস্ত কিছু পড়তে হবে, যদি আমরা exitএকই লাইনে mainরাখি যেহেতু আমরা নিশ্চিত করে ফেলি যে শেলটি ফাইলের পরে আর কিছু পড়বে না main
স্টাফেন চেজেলাস

1
@ মন্টিহার্ডার, আপনি ব্যবহার করেন কিনা তা বিবেচনাধীন নয় main; exit, main; exit $?বা main <EOF>সমস্ত ক্ষেত্রেই mainস্ক্রিপ্টের প্রস্থান কোড হিসাবে প্রস্থান কোড ব্যবহার করা হয়। exitকেউ স্ক্রিপ্ট যখন এটি চালাচ্ছে সম্পাদনাগুলি যদি শুধু জিনিষ আপ তছনছ পেয়ে প্রতিরোধ করা হবে।
ইলক্কাচু

13

না, ফাংশনগুলি তাদের কল করার সময় শাঁস পরিবেশে বিদ্যমান থাকতে হবে।

গুগলের "শেল স্টাইল গাইড" এর এটির একটি সমাধান রয়েছে:

mainকমপক্ষে অন্য একটি ফাংশন ধারণ করার জন্য স্ক্রিপ্টগুলির জন্য দীর্ঘস্থায়ী একটি ফাংশন প্রয়োজন।

স্ক্রিপ্টের একেবারে শেষে, সমস্ত ক্রিয়াকলাপের পরে, কোনও ফাংশন নয়, কেবলমাত্র বিবৃতি হিসাবে

main "$@"

এটি mainস্ক্রিপ্টটি যা পরামিতি দিয়েছিল তা দিয়ে ফাংশনটিকে কল করবে । mainফাংশন স্ক্রিপ্ট শীর্ষে অবস্থিত যেতে পারে (শৈলী গাইড নীচে এটা করা বলছে, কিন্তু তারপর আবার, এটা অনেক কিছু বলেছেন)।

শেলটি mainকল এলে, স্ক্রিপ্টের সমস্ত ফাংশন পার্স করা হয়েছে এবং তাই mainফাংশনটির মধ্যে থেকে কল করা যেতে পারে।


9

না, ফাংশনগুলি ব্যবহারের আগে তাদের ঘোষণা করতে হবে। শেল স্ক্রিপ্টগুলি এক এক করে লাইনে পঠিত হয় এবং লাইনে লাইনে অভিনয় করা হয়; সুতরাং কোনও ঘোষণা কার্যকর না হওয়া পর্যন্ত কোনও ফাংশন বিদ্যমান থাকে না।


আপনার ঠিক আছে। সমস্যাটি আমার কাছে একটি স্ক্রিপ্টে 30+ ফাংশন রয়েছে। কোডটি পড়লে এটি বেশ জটিল ইন Cএটা আরামদায়ক নয়।
এমএসপি 9011

3
আপনি আপনার ফাংশন ঘোষণাগুলি অন্য কোনও ফাইলে রাখতে পারেন এবং এটি উত্স তৈরি করতে পারেন ( . yourfile)।
স্টিফেন কিট

হ্যাঁ, আমি এটি চেষ্টা করেছি, তবে প্রয়োজনীয়তার জন্য একটি একক স্ক্রিপ্ট থাকা দরকার।
এমএসপি 9011

@ শিবাপ্রসথ ঠিক সমস্যা কি? সমস্ত ফাংশন কেবলমাত্র সংজ্ঞায়িত করুন, এমনকি কোনও ফাংশনে মূল কোডটি রেখে দেওয়া এবং তারপরে শেষ পংক্তিটি দেখায় যে কোন ফাংশনটি বলা হয় এবং এতে স্ক্রিপ্টের মূল অংশ থাকে।
ব্ল্যাকজ্যাক

@ शिवপ্রসত সি তে, আপনার ifকাছে কোনও ফাংশনের বাইরে খালি বিবৃতি নেই। ফাংশন সংজ্ঞায়িত করা যখন আপনি নেই ডিক্লেয়ারif -containing ফাংশন ঠিক যখন আপনি কল করুন।
চিপনার

4

শেলটির কোনও declaringফাংশনের ধারণা নেই । সুতরাং আপনার কোনও অগ্রণী ঘোষণা থাকতে পারে না।

ফলস্বরূপ, ফাংশন বাস্তবায়ন শেলটি কল করার আগে এটি পড়া উচিত।


4
প্রযুক্তিগতভাবে কিছু শেলের (ksh, zsh) একটি ফাংশন অটোলয়েডিং বৈশিষ্ট্য রয়েছে যা এটি ঘোষণার কিছু ফর্ম হিসাবে দেখা যেতে পারে (যেখানে autoload fফাংশনটি ঘোষণা করে তবে এর দেহটি কেবল প্রথম অনুরোধের পরে বোঝাই হয়)। এটি bashযদিও ওপির ক্ষেত্রে প্রযোজ্য নয় ।
স্টাফেন চেজেলাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.