"फ़ंक्शन फू () {}" और "फू () {}" के बीच अंतर


96

मैं कीवर्ड bashका उपयोग करके या उसे छोड़ कर कार्यों को परिभाषित कर सकता हूं function। क्या कोई अंतर है?

#!/bin/bash

function foo() {
  echo "foo"
}

bar() {
  echo "bar"
}

foo

bar

दोनों कार्यों को कहते हैं fooऔर barसफल होते हैं और मैं कोई अंतर नहीं देख सकता। इसलिए मैं सोच रहा हूं कि क्या यह केवल पठनीयता में सुधार करना है, या ऐसा कुछ है जो मुझे याद आ रहा है ...

अन्य गोले में BTW की तरह dash( /bin/shयह dashडेबियन / ubuntu में सहानुभूति है ) यह functionकीवर्ड का उपयोग करते समय विफल रहता है ।


8
कोष्ठक के साथ या इसके बिना function baz { echo "baz"; }:। देखें Bashism GreyCat का विकी में।
मैनेटवर्क

जवाबों:


42

AFAIK में कोई अंतर नहीं है, इस तथ्य के अलावा कि दूसरा संस्करण अधिक पोर्टेबल है।


32
यह एक बड़ा अंतर है, पोर्टेबिलिटी ... मुझे बहुत सारे उत्तर दिखाई देते हैं जो केवल (पुराने) उत्पादन प्रणालियों पर काम नहीं करते हैं, और कई ऐसे विकल्प भी हैं जो केवल लिनक्स पर काम करते हैं। कम से कम, चेतावनी दें कि यह सबसे पोर्टेबल तरीका नहीं है ... यह बिल्कुल खतरनाक हो सकता है (किसी को tar cf - /some/thing | ssh user@desthost "cd destinationdir && tar xf - " बिना चेतावनी दिए उन्हें पहले डबल-चेक करने के लिए कहा जाता है कि क्या डेस्टहोस्ट पर टार के संस्करण को "/" से छुटकारा मिल सकता है) कुछ मामलों में आपदाएं ...)। पूर्व के लिए: यदि एक का उपयोग करें function tar { #a safe tar with safety checks ... }और shइसे अनदेखा करता है, ...
ओलिवियर दुलैक

1
@OlivierDulac मैं वह स्क्रिप्ट जोड़ूंगा जो मानती shहै कि functionकीवर्ड को मान्यता देता है - और, सामान्य रूप से, जो सामान्य लेकिन गैर-मानक विशेषताओं को ग्रहण करता है, जो कि गोले को पसंद करते हैं kshऔर bashऑफ़र करते हैं - अक्सर नए उत्पादन प्रणालियों पर भी काम नहीं करेंगे , भले ही वे पुराने रिलीज पर काम करते हों वही OS bashअभी भी shकई GNU / Linux सिस्टम प्रदान करता है , लेकिन कुछ लोकप्रिय डिस्ट्रोस ने प्रदर्शन में सुधार के लिए सिम्बलिन (डेबियन अल्मक्विस्ट SHell) के shरूप में स्विच किया है dash। इसमें डेबियन और उबंटू शामिल हैं
एलियाह कगन

2
यह बताए बिना कि यह "अधिक पोर्टेबल" कैसे है, इसका जवाब उपयोगी नहीं है।
ivan_pozdeev

पोर्टेबिलिटी आजकल कोई तर्क नहीं है जहां उद्योग सभी वातावरणों के 99.9% में बैश या समकक्ष शेल का उपयोग कर रहा है। यह पठनीयता के लिए उबलता है और दो पक्ष हैं: कुछ लोग कहते हैं कि "फ़ंक्शन" यह स्पष्ट करता है, जो लोग इसे पॉज़िक्स मानकों या अन्य गोले से सीखते हैं वे कहेंगे ब्रेसिज़ अधिक स्पष्ट शैली हैं। अंत में, अपने समूह या कंपनी में से किसी एक को चुनें और उससे चिपके रहें।
ह्यूबर्ट ग्रेज्सकोविआक

92

functionकीवर्ड में पेश किया गया था ksh । पारंपरिक बॉर्न शेल में केवल foo ()सिंटैक्स था, और पोसिक्स केवल foo ()सिंटैक्स का मानकीकरण करता है।

ATT ksh (लेकिन pdksh नहीं) में, functionबॉर्न / POSIX सिंटैक्स के साथ परिभाषित कार्यों और कार्यों के बीच कुछ अंतर हैं । द्वारा परिभाषित फ़ंक्शन में 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 ATT ksh का अनुकरण नहीं करता है। Pdksh में, typesetफ़ंक्शन की परवाह किए बिना स्थानीय रूप से स्कोप किए गए चर बनाता है, और कोई स्थानीय जाल नहीं हैं (हालांकि उपयोग functionकुछ मामूली अंतर करता है - विवरण के लिए मैन पेज देखें)।

बैश और zsh ने functionksh के साथ संगतता के लिए कीवर्ड पेश किया । हालांकि इन गोले में function foo { … }और foo () { … }सख्ती से समान हैं, जैसा कि बैश और जेडश विस्तार है function foo () { … }typesetकीवर्ड हमेशा (साथ छोड़कर स्थानीय चर वाणी -gनिश्चित रूप से), और जाल (आप की स्थापना करके zsh में स्थानीय जाल प्राप्त कर सकते हैं स्थानीय नहीं हैं local_trapsविकल्प)।


8
यह ध्यान दिया जाना चाहिए कि बॉर्न शेल के सिंटैक्स को पेश करने से पहले फंक्शन सपोर्ट कोर्न शेल foo() commandमें जोड़ा गया था, और बॉर्न सिंटैक्स को बाद में संगतता के लिए कोर्न शेल में जोड़ा गया था।
स्टीफन चेजलस

2
क्या यह सही है कि कीवर्ड के बाद function { ... }; f;चूक जाता है ? ffunction
रुस्लान

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)... सबसे अधिक इस्तेमाल किया जा रहा है { ...; })

POSIX सिंटैक्स किसी बॉर्न जैसे शेल द्वारा समर्थित है और एक जिसे आप आमतौर पर उपयोग करना चाहते हैं।

function foo { ...; }

कोर्न शेल सिंटैक्स है, जो बॉर्न सिंटैक्स से पहले है। केवल इस एक का उपयोग करें यदि केंट शेल के एटी एंड टी कार्यान्वयन के लिए विशेष रूप से लिख रहे हैं और इसे प्राप्त होने वाले विशिष्ट उपचार की आवश्यकता है। यह सिंटैक्स POSIX नहीं है, लेकिन इसके द्वारा समर्थित है bash, yashऔर zshकोर्न शेल के साथ संगतता के लिए हालांकि उन गोले (और pdkshकोर्न शेल के -बेड वेरिएंट) इसे मानक सिंटैक्स से अलग नहीं मानते हैं।

function foo () { ...; }

की वाक्य रचना है कोई खोल और नहीं किया जाना चाहिए । यह केवल द्वारा दुर्घटना द्वारा समर्थित होना करने के लिए होता bash, yash, zshऔर pdkshकॉर्न खोल के आधार वेरिएंट। संयोग से, यह awkफ़ंक्शन सिंटैक्स भी है ।

यदि हम गूढ़ सूची में नीचे जा रहे हैं,

function foo() other-compound-command

(like function foo() (subshell)or 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 ]। बैश में 4.1.11 से कम से कम 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। आरक्षित शब्द फ़ंक्शन वैकल्पिक है। यदि फ़ंक्शन आरक्षित शब्द की आपूर्ति की जाती है, तो कोष्ठक वैकल्पिक होते हैं।

EDIT: मैंने अभी देखा कि यह प्रश्न टैग है posix। POSIX में sh, functionकीवर्ड का उपयोग नहीं किया जाता है (हालांकि यह आरक्षित है)।


3

कई अन्य लोगों ने अब तक सही उत्तर दिया है, लेकिन यहाँ मेरा संक्षिप्त सार है:

दूसरा संस्करण पोर्टेबल है और कई मानक (विशेष रूप से POSIX) के गोले के साथ काम करने की संभावना है।

पहला संस्करण केवल बैश के साथ काम करेगा, लेकिन आप इसके साथ फ़ंक्शन नाम के बाद कोष्ठक को छोड़ सकते हैं।

अन्यथा, वे मार खाने के बाद समान संस्थाओं का प्रतिनिधित्व करते हैं।


वास्तव में, पहले संस्करण को कुछ गोले के लिए स्वीकार्य वाक्यविन्यास के रूप में सीमित करने के अलावा कोई मतलब नहीं है । जब आप शामिल () औरfunction कीवर्ड खोल बर्ताव करता है जैसे कि आप अभी किया foo(){ ...; }वैसे भी, को छोड़कर, ज़ाहिर है, एक खोल जिसमें यह अवैध वाक्य रचना है। और इसलिए आपको चाहिए function foo { ...; }तो आपको करना चाहिए, foo(){ ...; }अन्यथा नहीं।
mikeserv
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.