किसी फ़ंक्शन के अंदर से फ़ंक्शन का नाम कैसे निर्धारित करें


163

अगर मेरे पास बैश स्क्रिप्ट है जैसे:

#!/bin/bash

f() {
  # echo function name, "f" in this case
}

क्या इसे करने का कोई तरीका है? इसका उपयोग मदद संदेशों जैसे में किया जा सकता है

printf "Usage: %s: blah blah blah \n" $(basename $0) >&2; 

केवल इस मामले में जो मैं चाहता था वह नहीं है $0, जो स्क्रिप्ट का फ़ाइल नाम है।


2
संबंधित: बैश लॉगिंग फ्रेमवर्क जो FUNCNAMEसरणी और अन्य बैश चर का उपयोग करता है : github.com/codeforester/base/blob/master/lib/stdlib.sh । कार्यों log_debug_enterऔर log_debug_leaveविशेष रूप से देखें ।
कोडप्रोस्टर

जवाबों:


236

आप उपयोग कर सकते हैं ${FUNCNAME[0]}में bashसमारोह नाम मिलता है।


79

से बैश संदर्भ मैनुअल :

FUNCNAME

एक शेल वैरिएबल जिसमें सभी शेल फ़ंक्शंस के नाम हैं जो वर्तमान में निष्पादन कॉल स्टैक में हैं। इंडेक्स 0 वाला तत्व किसी भी वर्तमान में निष्पादित शेल फ़ंक्शन का नाम है। नीचे-सबसे तत्व (उच्चतम सूचकांक वाला) "मुख्य" है। यह चर केवल तब होता है जब शेल फ़ंक्शन निष्पादित हो रहा हो। FUNCNAME को असाइनमेंट का कोई प्रभाव नहीं है और एक त्रुटि स्थिति लौटाता है। यदि FUNCNAME परेशान है, तो यह अपने विशेष गुणों को खो देता है, भले ही यह बाद में रीसेट हो।

इस चर का उपयोग BASH_LINENO और BASH_SOURCE के साथ किया जा सकता है। FUNCNAME के ​​प्रत्येक तत्व में कॉल स्टैक का वर्णन करने के लिए BASH_LINENO और BASH_SOURCE में संबंधित तत्व हैं। उदाहरण के लिए, $ {FUNCNAME [$ i]} को फ़ाइल से $ {BASH_SOURCE [$ i + 1]} लाइन नंबर $ {BASH_LINENO [$ i]} पर कॉल किया गया था। इस जानकारी का उपयोग कर कॉल करने वाला बिलियन वर्तमान कॉल स्टैक को प्रदर्शित करता है।

जब बैश सरणियों को एक इंडेक्स के बिना एक्सेस किया जाता है, तो एरे का पहला तत्व वापस आ जाएगा, इसलिए $FUNCNAMEतत्काल मामलों में तत्काल फ़ंक्शन का नाम प्रदान करने के लिए सरल मामलों में काम करेगा, लेकिन इसमें कॉल स्टैक में अन्य सभी फ़ंक्शन भी शामिल हैं। उदाहरण के लिए:

# in a file "foobar"
function foo {
    echo foo
    echo "In function $FUNCNAME: FUNCNAME=${FUNCNAME[*]}" >&2
}

function foobar {
    echo "$(foo)bar"
    echo "In function $FUNCNAME: FUNCNAME=${FUNCNAME[*]}" >&2
}

foobar

उत्पादन होगा:

$ bash foobar
In function foo: FUNCNAME=foo foobar main
foobar
In function foobar: FUNCNAME=foobar main

6
मैं अभी भी नहीं मिला। [0]यदि यह अघोषित चर का उपयोग करके निहित है , तो क्यों जोड़ें ?
टॉम हेल

15
क्योंकि यह चर के वास्तविक प्रकार से भ्रामक और अज्ञानी है? निश्चित रूप से, यह हमेशा आवश्यक नहीं होता है, लेकिन कई अन्य बैश-आइम्स की तरह, यह एक आलसी सम्मेलन है। अस्पष्ट से स्पष्ट होना बेहतर है।
bschlueter

36

मैं ${FUNCNAME[0]}वर्तमान फ़ंक्शन नाम मुद्रित करने के लिए उपयोग करता हूं


@bschlueter लेकिन जब आप किसी सरणी को बैश में एक सरणी की तरह व्यवहार किए बिना संदर्भित करते हैं, तो यह पहले मूल्य को प्रिंट करता है; इसलिए, स्वीकृत उत्तर गलत कैसे है?
एलेक्सज मगुरा

4
यकीन है, और यह सुविधाजनक है, लेकिन रखरखाव और परीक्षण के लिए भयानक है। आलसी मत बनो, स्पष्ट रहो।
bschlueter

1

एक और उदाहरण:

# in a file "foobar"
foo() {
    echo "$FUNCNAME fuction begins"
}

foobar() {
    echo "$FUNCNAME fuction begins"
}

echo 'begin main'
foo
foobar
echo 'end main'

उत्पादन होगा:

begin main
foo fuction begins
foobar fuction begins
end main

-1

फ़ंक्शन नाम प्राप्त करने का सबसे सरल तरीका (एक फ़ंक्शन के अंदर से)

echo $0

कृपया ###अपने उत्तरों में गाली देना बंद करें ।
Marcin Orlowski

@MarcinOrlowski क्या आप ठीक कर रहे हैं? लगता है कि आप गले लगा सकते हैं।
jasonleonhard
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.