"ফাংশন foo () {}" এবং "foo () {}" এর মধ্যে পার্থক্য


96

আমি কীওয়ার্ডটি bashব্যবহার করে বা বাদ দিয়ে ফাংশনগুলি সংজ্ঞায়িত করতে পারি function। কোন পার্থক্য আছে?

#!/bin/bash

function foo() {
  echo "foo"
}

bar() {
  echo "bar"
}

foo

bar

উভয় ফাংশনে কল fooএবং barসফল এবং আমি কোনও পার্থক্য দেখতে পাচ্ছি না। তাই আমি ভাবছি যে এটি কেবল পাঠযোগ্যতার উন্নতি করার জন্য, বা এমন কিছু আছে যা আমি মিস করছি ...

অন্যান্য শেলগুলির মতো বিটিডাব্লু dash( /bin/shযেমন dashডেবিয়ান / উবুন্টুতে সিমলিংকযুক্ত) functionকীওয়ার্ডটি ব্যবহার করার সময় এটি ব্যর্থ হয় ।


8
এছাড়াও সহ বা প্রথম বন্ধনী ছাড়া: function baz { echo "baz"; }গ্রেগেটের উইকিতে বাশিজম দেখুন ।
manatwork

উত্তর:


42

দ্বিতীয় সংস্করণটি আরও বহনযোগ্য fact


32
এটি একটি বিরাট পার্থক্য, বহনযোগ্যতা ... আমি অনেকগুলি উত্তর দেখতে পাচ্ছি যা কেবলমাত্র (পুরানো) উত্পাদন সিস্টেমগুলিতে কাজ করে না, এবং এমন অনেকগুলি বিকল্প রয়েছে যা কেবলমাত্র লিনাক্সে কাজ করে। কমপক্ষে, সতর্ক করুন যে এটি সর্বাধিক পোর্টেবল উপায় নয় ... এটি নিখুঁত বিপজ্জনক হতে পারে (কাউকে জিজ্ঞাসা tar cf - /some/thing | ssh user@desthost "cd destinationdir && tar xf - " না করে প্রথমে ডাবল-চেক না করে ডেসথস্টের ট্যারের সংস্করণ "/" থেকে মুক্তি পেতে পারে কিনা তা জানতে চাইলে কিছু ক্ষেত্রে বিপর্যয় ...)। প্রাক্তন হিসাবে: যদি এটি ব্যবহার করে function tar { #a safe tar with safety checks ... }এবং shএটিকে উপেক্ষা করে, ...
অলিভিয়ার ডুলাক

1
@ অলিভিয়ারডুলাক আমি সেই স্ক্রিপ্টগুলি যুক্ত করব যা মূলশব্দটি shসনাক্ত করে function- এবং সাধারণভাবে শেলগুলি পছন্দ করে kshএবং bashপ্রস্তাব দেয় এমন সাধারণ তবে নন-মানসম্মত বৈশিষ্ট্যগুলি ধরে রাখে - প্রায়শই তারা নতুন প্রযোজনা সিস্টেমে কাজ করবে না , এমনকি তারা পুরানো প্রকাশগুলিতে কাজ করলেও একই ওএস bashএখনও shঅনেকগুলি জিএনইউ / লিনাক্স সিস্টেম সরবরাহ করে তবে কিছু জনপ্রিয় ডিস্ট্রো পারফরম্যান্সের উন্নতি shকরতে dash(দেবিয়ান অ্যালকুইস্ট শেল) এর সিমিলিংক হিসাবে স্যুইচ করেছে। এর মধ্যে রয়েছে দেবিয়ান এবং উবুন্টু
এলিয়াহ কাগান

2
কীভাবে এটি "আরও পোর্টেবল" ঠিক তা ব্যাখ্যা না করে উত্তরটি কার্যকর হয় না।
আইভান_পোজদেদেভ

আজকাল পোর্টেবলিটি কোনও যুক্তি নয় যেখানে শিল্পটি সমস্ত পরিবেশের 99.9%% এ ব্যাশ বা সমমানের শেল ব্যবহার করছে। এটি পাঠযোগ্যতার দিকে ফোটায় এবং এর দুটি দিক রয়েছে: কিছু লোক "ফাংশন" বলে তা স্পষ্ট করে তোলে, যে ব্যক্তিরা এটি পিক্সিক মান বা অন্যান্য শেল থেকে শিখেছে তারা বলবে ব্রেসগুলি আরও স্পষ্ট শৈলী। শেষ পর্যন্ত, আপনার গ্রুপ বা সংস্থার মধ্যে একটি চয়ন করুন এবং এর সাথে লেগে থাকুন।
হুবার্ট গ্রাজেসকুইয়াক

92

মূল functionশব্দটি ksh এ চালু হয়েছিল । ঐতিহ্যগত বোর্ন শেল শুধুমাত্র ছিল foo ()সিনট্যাক্স এবং POSIX শুধুমাত্র standardizes foo ()সিনট্যাক্স।

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

$ ksh -c 'a=global; f () { typeset a=local; }; f; echo $a'
local
$ ksh -c 'a=global; function f { typeset a=local; }; f; echo $a'
global

Ksh- এ আর একটি পার্থক্য হ'ল functionকীওয়ার্ডের সাথে সংজ্ঞায়িত ফাংশনগুলির নিজস্ব ট্র্যাপ প্রসঙ্গ রয়েছে। ফাংশনটির বাইরে নির্ধারিত ফাঁদগুলি ফাংশনটি সম্পাদন করার সময় উপেক্ষা করা হয় এবং ফাংশনের অভ্যন্তরে মারাত্মক ত্রুটিগুলি কেবল ফাংশন থেকে প্রস্থান করে পুরো স্ক্রিপ্ট থেকে নয়। এছাড়াও, $0কোনও ফাংশনে ফাংশনের নাম দ্বারা সংজ্ঞায়িত করা হয় functionতবে কোনও ফাংশনে স্ক্রিপ্ট নামটি সংজ্ঞায়িত করা হয় ()

Pdksh এটিটি ksh অনুকরণ করে না। পিডিক্সে, typesetফাংশন নির্বিশেষে স্থানীয়ভাবে স্কোপযুক্ত ভেরিয়েবলগুলি তৈরি করে এবং স্থানীয় কোনও ফাঁদ নেই (যদিও ব্যবহারের functionফলে কিছুটা ছোট পার্থক্য হয় - বিশদটির জন্য ম্যান পৃষ্ঠাটি দেখুন)।

বাশ এবং zsh functionksh এর সাথে সামঞ্জস্যের জন্য কীওয়ার্ডটি চালু করেছিল introduced তবে এই শেলগুলিতে function foo { … }এবং foo () { … }কঠোরভাবে অভিন্ন, যেমন বাশ এবং জেড এক্সটেনশন function foo () { … }typesetশব্দ সবসময় (সাধারণ আলোচনা ছাড়া স্থানীয় ভেরিয়েবল ঘোষণা -gঅবশ্যই), এবং যাত্রীর সঙ্গের নিজলটবহর (আপনি সেটিং দ্বারা zsh স্থানীয় যাত্রীর সঙ্গের নিজলটবহর পেতে পারেন স্থানীয় নয় local_trapsবিকল্প)।


8
এটি লক্ষ করা উচিত যে বোর্ন শেলটি সিনট্যাক্স প্রবর্তনের আগে কার্ন শেলের সাথে ফাংশন সমর্থন যুক্ত করা হয়েছিল foo() commandএবং পরে বোর্ন সিনট্যাক্সটি সামঞ্জস্যের জন্য কর্ন শেলটিতে যুক্ত করা হয়েছিল।
স্টাফেন চেজেলাস

2
কীওয়ার্ডের পরে function { ... }; f;বাদ fপড়ে এটি কি সঠিক function?
রুসলান

32
foo() any-command

বোর্ন সিনট্যাক্স কোনো বোর্ন মত শেল কিন্তু দ্বারা সমর্থিত নয় bash, yashএবং সাম্প্রতিক সংস্করণটি posh(শুধুমাত্র যৌগ কমান্ড সমর্থন যা)। (বোর্ন শেল এবং এটিএন্ডটি বাস্তবায়ন কোনও যৌগিক কমান্ড kshনা থাকলে সমর্থন করে foo() any-command > redirectionsনা any-command)।

foo() any-compound-command

(যৌগ উদাহরণ কম্যান্ড: { cmd; }, for i do echo "$i"; done, (cmd)... সবচেয়ে বেশি ব্যবহৃত হচ্ছে { ...; })

পসিক্স সিনট্যাক্সটি কোনও বোর্নের মতো শেল এবং আপনি সাধারণত ব্যবহার করতে চান এমন একটি দ্বারা সমর্থিত।

function foo { ...; }

এটি কর্ন শেল সিনট্যাক্স, যা বোর্ন সিনট্যাক্সের পূর্বাভাস দেয়। শুধুমাত্র এটি ব্যবহার করুন যদি কর্ন শেলটির এটিএন্ডটি বাস্তবায়নের জন্য বিশেষভাবে লেখা হয় এবং সেখানে এটি প্রাপ্ত নির্দিষ্ট চিকিত্সার প্রয়োজন হয়। এই সিনট্যাক্সটি পসিক্স নয়, তবে এটি দ্বারা সমর্থিত bash, yashএবং zshকর্ন শেলের সাথে সামঞ্জস্যের জন্য যদিও এই শেলগুলি (এবং pdkshকর্ন শেলের মূল ভিত্তিযুক্ত রূপগুলি) এটি স্ট্যান্ডার্ড সিনট্যাক্সের চেয়ে আলাদা মনে করে না।

function foo () { ...; }

কোনও শেলের সিনট্যাক্স এবং ব্যবহার করা উচিত নয় । এটা শুধুমাত্র দ্বারা দুর্ঘটনা দ্বারা সমর্থিত হতে ঘটবে bash, yash, zshএবং pdkshKorn থেকে শেলের ভিত্তিক রূপগুলো। ঘটনাচক্রে, এটি awkফাংশন সিনট্যাক্সও।

আমরা যদি রহস্যজনক তালিকায় নামতে থাকি,

function foo() other-compound-command

(মত function foo() (subshell)বা function foo() for i do; ... done) আরও খারাপ। এটি সমর্থিত bash, yashএবং zsh, তবে ksh নয়, এমনকি- pdkshভিত্তিক বৈকল্পিক।

যদিও:

function foo() simple command

শুধুমাত্র দ্বারা সমর্থিত zsh


1
কী- functionওয়ার্ড এবং প্রথম বন্ধনী উভয়কে অন্তর্ভুক্ত করে এমন সিনট্যাক্সটি বাশ-এ নথিভুক্ত করা হয়েছে। 4.2 বাশের ম্যানুয়াল এবং পরে বলেছে যে ফাংশনগুলি সিনট্যাক্স দ্বারা ঘোষণা করা হয় name () compound-command [ redirections ]বা function name [()] compound-command [ redirections ]। বাশ ৪.১.১১-তে কমপক্ষে 3.0.০-বিটাতে নেমে এসেছিল [ function ] name () compound-command [redirection]যা কেবলমাত্র একক লাইন যা ভুলক্রমে মূল বাক্যাংশটি অন্তর্ভুক্ত করে তাতে মূল functionশব্দটি নয় তবে বন্ধনীগুলি নয় তবে এখনও বাক্যবিন্যাসকে আবরণ করে না যা functionকীওয়ার্ড এবং প্রথম বন্ধনী উভয়ই অন্তর্ভুক্ত করে ।
নিসেতামা

@ নিস, মূল বিষয়টি হচ্ছে যে কর্ন শেলের সাথে সামঞ্জস্যতা ছাড়াও bashস্বীকৃতি দেয় (এবং সর্বদা থাকে) যাতে এটি কর্ন শেলের জন্য লিখিত স্ক্রিপ্টগুলির ব্যাখ্যা করতে পারে। এটি পাশাপাশি সমর্থন করে তবে এটি ব্যবহার করার কোনও ভাল কারণ নেই। function foo {foo() {function foo () {
স্টাফেন চেজেলাস

2
@ স্টাফেনচেজেলাস ভাল, আমি বলতে পারি যে ব্যবহার করার উপযুক্ত কারণ আছে function f() {। যথা, পঠনযোগ্যতার নিরিখে, এটি ইংরেজী জানে এমন কেউ এবং সি কে জানে এমন যে কেউ এই সেটের মধ্যে একটির বিপরীতে একটি ফাংশন হিসাবে স্বীকৃত হতে চলেছে।
হতাশডানিয়েল

2
গ্রহণযোগ্য উত্তর হওয়া উচিত। সত্যই গুরুত্বপূর্ণYou should never combine the keyword function with the parentheses () when defining a function.
4wk_

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

22

শব্দার্থকভাবে, এই দুটি ফর্ম বাশের সমতুল্য।

ম্যান পৃষ্ঠা থেকে:

শেল ফাংশন নীচে ঘোষণা করা হয়:

name () compound-command [redirection]
function name [()] compound-command [redirection]

এটি নামের একটি ফাংশন সংজ্ঞায়িত করে name। সংরক্ষিত শব্দ ফাংশন isচ্ছিক। যদি ফাংশন সংরক্ষিত শব্দ সরবরাহ করা হয় তবে প্রথম বন্ধনী alচ্ছিক।

সম্পাদনা: আমি সবেমাত্র লক্ষ্য করেছি যে এই প্রশ্নটি ট্যাগ করা আছে posix। পসিক্সে sh, functionকীওয়ার্ডটি ব্যবহার করা হয় না (যদিও এটি সংরক্ষিত থাকে)।


3

আরও কয়েকজন এখনই সঠিক উত্তর দিয়েছেন, তবে এখানে আমার সংক্ষিপ্ত প্রতিশ্রুতি রয়েছে:

দ্বিতীয় সংস্করণটি বহনযোগ্য এবং সম্ভবত অনেকগুলি স্ট্যান্ডার্ড (বিশেষত পসিক্স) শেল নিয়ে কাজ করবে।

প্রথম সংস্করণটি কেবল বাশ দিয়ে কাজ করবে তবে এটির সাথে ফাংশনটির নাম অনুসরণ করে আপনি প্রথম বন্ধনী বাদ দিতে পারেন।

অন্যথায়, বাশ তাদের ব্যাখ্যা করার পরে তারা অভিন্ন সত্তা উপস্থাপন করে।


প্রকৃতপক্ষে, প্রথম সংস্করণটি কিছু শেলের মধ্যে গ্রহণযোগ্য বাক্য গঠন হিসাবে সীমাবদ্ধ করা ছাড়া কোনও ধারণা দেয় না । যখন আপনি অন্তর্ভুক্ত () এবংfunction শব্দ শেল আচরণ করবে যেন আপনি ঠিক কি foo(){ ...; }যাহাই হউক না কেন ছাড়া, অবশ্যই, একটি শেল যেখানে এটি অবৈধ সিনট্যাক্স জন্য। এবং তাই আপনার অবশ্যই করা উচিত function foo { ...; }যদি আপনার প্রয়োজন হয়, বা foo(){ ...; }অন্যথায়।
মাইকজার্ভেস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.