2009-06-17 15 views
18

से कोई फ़ंक्शन मौजूद है या नहीं, मैं यह निर्धारित कैसे कर सकता हूं कि किसी फ़ंक्शन को किसी बैश स्क्रिप्ट में पहले से परिभाषित किया गया है या नहीं?जांचें कि कोई फ़ैश बैश स्क्रिप्ट

मैं अपने .bash_login स्क्रिप्ट को सिस्टम के बीच पोर्टेबल बनाने की कोशिश कर रहा हूं, इसलिए मैं केवल एक फ़ंक्शन को कॉल करने के लिए तर्क जोड़ना चाहता हूं यदि यह मौजूद है।

मैं __git_ps1()PS1 को केवल उस सिस्टम पर मौजूद करना चाहता हूं, तो केवल जोड़ना चाहता हूं। यह फ़ंक्शन आमतौर पर git-completion.bash में परिभाषित होता है जो कि गिट स्रोत के साथ आता है, या बंदरगाहों/एपीटी इंस्टॉल की बैश पूर्णता स्क्रिप्ट्स में से एक द्वारा।

उत्तर

10
if type __git_ps1 | grep -q '^function$' 2>/dev/null; then 
    PS1=whatever 
fi 
+0

'प्रकार' का उपयोग करना 'घोषणा' से बहुत तेज था - धन्यवाद। – csexton

+4

यह लगभग सही है, लेकिन यह "सत्य" भी लौटाएगा यदि '__get_ps1' उपनाम, बिल्टिन इत्यादि है। 'टाइप करें- function_name | grep -q "^ function $"; फिर ... fi', यह सुनिश्चित करने के लिए कि '__git_ps1' एक फ़ंक्शन है। –

+0

@ चेनलेवी: प्रति संपादित। – chaos

8

आप का उपयोग कर ऐसा कर सकते हैं:

type function_name 
में

मामले यह मौजूद है में अपने एक समारोह परिभाषा वापस आ जाएगी। तो जब भी आउटपुट खाली हो या नहीं, तो आप जांच सकते हैं।

पी एस। इससे भी बेहतर मैंने अभी जांच की है कि यह आउटपुट होगा कि फ़ंक्शन मौजूद नहीं है अन्यथा आउटपुट फ़ंक्शन बॉडी।

4

एफ 'function_name'>/dev/बातिल

गूंज $ घोषित?

$? परिणाम फ़ंक्शन मौजूद होने पर मान 0 है, 1 अन्यथा

0
if declare -F | grep __git_ps1$ 
then 
    PS1=whatever 
fi 
2

मुझे लगता है कि यह घोषित करने के लिए बेहतर है, भले ही यह प्रकार से थोड़ा धीमा हो। पाथ में मौजूद उपनाम या स्क्रिप्ट के लिए भी suceeds टाइप करें।

मैं इस का उपयोग कर रहा:

function function_exists 
{ 
    FUNCTION_NAME=$1 

    [ -z "$FUNCTION_NAME" ] && return 1 

    declare -F "$FUNCTION_NAME" > /dev/null 2>&1 

    return $? 
} 

तो बाद में मेरे लिपियों में मैं आसानी से देख सकते हैं क्या हो रहा है:

if function_exists __git_ps1 
then 
    PS1=__git_ps1 
fi 

या यहां तक ​​कि अभी भी पठनीय एक लाइनर:

function_exists __git_ps1 && PS1=__git_ps1 
1

आप सभी उपलब्ध कार्यों को सूचीबद्ध कर सकते हैं या compgen के साथ व्यक्तिगत कार्यों की जांच कर सकते हैं:

help compgen 

compgen -A function 

compgen -A function myfunc 1>/dev/null && echo 'myfunc already exists' || exit 1 
11

मुझे पता है यह एक पुराने सवाल है, लेकिन अन्य उत्तर में से कोई भी काफी के रूप में बस के रूप में मैं चाहता हूँ यह करते हैं। यह एक कुशल प्रकार के परीक्षण के रूप में type -t (चेन लेवी द्वारा एक टिप्पणी में सुझाए गए अनुसार) का उपयोग करता है, लेकिन फिर grep का आविष्कार करने के बजाय शैल स्ट्रिंग तुलना का उपयोग करता है।

if [ "$(type -t somefunc)" = 'function' ]; then 
    somefunc arg1 arg2 
fi 

और यह एक कदम और आगे ले जाने की है, यह भी परोक्ष रूप से काम करता है:

funcname=do_it_special_$somehow 
if [ "$(type -t $funcname)" != 'function' ]; then 
    funcname=do_it_normal 
fi 
$funcname arg1 arg2 
+0

मुझे वास्तव में यह समाधान पसंद है, हालांकि स्ट्रिंग में बैकटिक्स की तरह लग रहा है अजीब लग रहा है। भले ही, मैं निश्चित रूप से इसका उपयोग करूँगा। – csexton

+0

@csexton आप बैकटिक्स के बजाय '" $ (type -t somefunc) "का उपयोग कर सकते हैं। – wisbucky

5

आप एक /bin/sh अनुरूप संस्करण की आवश्यकता है, तो आप typeset या declare उपयोग नहीं कर सकते यह के रूप में एक समारोह परिभाषा के लिए परीक्षण करने के लिए एक खोल निर्मित नहीं है। -f विकल्प type पर कुछ सिस्टम पर उपलब्ध नहीं हो सकता है।

समाधान मैं पेश आंशिक रूप से पहले से ही अन्य उत्तर में शामिल है:

isFunction() { 
    type $1 | head -1 | egrep "^$1.*function\$" >/dev/null 2>&1; 
    return; 
} 

isFunction __git_ps1 && PS1=__git_ps1 
0

ध्यान दें, बिजीबॉक्स (न्यूनतम एक खोल कार्यान्वयन में सभी, उदाहरण के लिए विंडोज पर उपयोगी) "प्रकार" लेकिन "टाइप आयकर" है गलत चीज प्रिंट करता है, इसलिए मैं कुछ प्रकार के कॉल करने योग्य देखने के लिए प्रकार के वापसी मूल्य की जांच करता हूं। व्यस्त बॉक्स में भी घोषणा नहीं की गई है।

संबंधित मुद्दे