मैं कमांड लाइन में स्क्रिप्ट से फ़ंक्शन कैसे चला सकता हूं?


119

मेरे पास एक स्क्रिप्ट है जिसमें कुछ कार्य हैं।

क्या मैं कमांड लाइन से सीधे फ़ंक्शन को चला सकता हूं?

कुछ इस तरह?

myScript.sh func()

जवाबों:


66

यदि स्क्रिप्ट केवल फ़ंक्शन को परिभाषित करती है और कुछ और नहीं करती है, तो आप पहले स्क्रिप्ट को वर्तमान शेल के संदर्भ में sourceया .कमांड का उपयोग करके निष्पादित कर सकते हैं और फिर बस फ़ंक्शन को कॉल कर सकते हैं। help sourceअधिक जानकारी के लिए देखें ।


1
इस पद्धति के साथ एकमात्र समस्या यह है कि यदि आप exitअपने फ़ंक्शन में उपयोग करते हैं, तो यह फ़ंक्शन निष्पादित होने के बाद टर्मिनल को बंद कर देगा। क्या इसके आसपास कोई रास्ता है? @SvenMarnach
user1527227

@ user1527227: उस स्थिति में अगले उत्तर के साथ जाएं, क्योंकि आपके पास शेल स्क्रिप्ट का नियंत्रण है। यदि आप ऐसा नहीं करते हैं, तो आप एक इंटरेक्टिव सबमिशन को पहले कॉल कर सकते हैं (केवल दर्ज करें bash), और exitकेवल सब्स्क्रिप्शन को समाप्त कर देंगे, लेकिन आपके टर्मिनल को नहीं।
स्वेन मार्नाच

238

ठीक है, जबकि अन्य उत्तर सही हैं - आप निश्चित रूप से कुछ और कर सकते हैं: यदि आपके पास बैश स्क्रिप्ट तक पहुंच है, तो आप इसे संशोधित कर सकते हैं, और बस अंत में विशेष पैरामीटर रख सकते हैं "$@"- जो कमांड लाइन के तर्कों तक विस्तृत होगा आप निर्दिष्ट करते हैं, और चूंकि यह "अकेला" है, इसलिए शेल उन्हें शब्दशः कहने की कोशिश करेगा; और यहाँ आप पहले तर्क के रूप में फ़ंक्शन नाम निर्दिष्ट कर सकते हैं। उदाहरण:

$ cat test.sh
testA() {
  echo "TEST A $1";
}

testB() {
  echo "TEST B $2";
}

"$@"


$ bash test.sh
$ bash test.sh testA
TEST A 
$ bash test.sh testA arg1 arg2
TEST A arg1
$ bash test.sh testB arg1 arg2
TEST B arg2

पॉलिश के लिए, आप पहले सत्यापित कर सकते हैं कि कमांड मौजूद है और एक फ़ंक्शन है:

# Check if the function exists (bash specific)
if declare -f "$1" > /dev/null
then
  # call arguments verbatim
  "$@"
else
  # Show a helpful error
  echo "'$1' is not a known function name" >&2
  exit 1
fi

16
"$@"ज्यादातर मामलों में उपयोग करें । $@कुछ मामलों में सुरक्षित नहीं है।
फ्यूमियास

1
एक फ़ंक्शन से अधिक कैसे चलाया जाए? उदाहरण के लिए क्या मैं चला सकता हूं bash test.sh testA testB?
जेफ पैंग

यह भी [ ! -z "$1" ]अन्यथा स्रोत के साथ लिपटे जाने की जरूरत है कुछ बाश verions में अन्य बयान
JackLeo

मैं इस जादुई "$ @" चर के लिए निकट और दूर तक खोज रहा हूं, जो भी किसी फ़ंक्शन पर उपयोग करने के लिए फ़ाइल में बुलाया जाता है, धन्यवाद @sdaau!
जस्टिन हैमंड

36

निम्न आदेश पहले संदर्भ में फ़ंक्शन को पंजीकृत करता है, फिर उसे कॉल करता है:

. ./myScript.sh && function_name

1
आप केवल स्रोत का उपयोग भी कर सकते हैं। जैसे - स्रोत
myScript.sh

17

संक्षेप में, नहीं।

आप स्क्रिप्ट के सभी कार्यों को अपने वातावरण में आयात कर सकते हैं source(help source विवरण के लिए) के , जो तब आपको उन्हें कॉल करने की अनुमति देगा। यह स्क्रिप्ट को निष्पादित करने का प्रभाव भी है, इसलिए ध्यान रखें।

शेल स्क्रिप्ट से किसी फ़ंक्शन को कॉल करने का कोई तरीका नहीं है जैसे कि यह एक साझा लाइब्रेरी थी।


1
मुझे लगता है कि इसे उचित जवाब के रूप में अधिक वजन दिया जाना चाहिए। मैंने कुछ ऐसा ही करने की कोशिश की, जो ओपी चाहता है, लेकिन शेल स्क्रिप्टिंग केवल "क्लीन-कट, ओओपी विकास" (आईएमएचओ) के लिए इंजीनियर नहीं है।
दान एल

4

का उपयोग करते हुए case

#!/bin/bash

fun1 () {
    echo "run function1"
    [[ "$@" ]] && echo "options: $@"
}

fun2 () {
    echo "run function2"
    [[ "$@" ]] && echo "options: $@"
}

case $1 in
    fun1) "$@"; exit;;
    fun2) "$@"; exit;;
esac

fun1
fun2

यह स्क्रिप्ट फ़ंक्शन फ़न 1 और फ़न 2 चलाएगी, लेकिन यदि आप इसे फ़न फ़न 1 या फ़न 2 से शुरू करते हैं, तो यह केवल दिए गए फ़ंक्शन को आर्ग्स (यदि प्रदान किया गया है) और बाहर निकलें। प्रयोग

$ ./test 
run function1
run function2

$ ./test fun2 a b c
run function2
options: a b c

1

संपादित करें: चेतावनी - ऐसा लगता है कि यह सभी मामलों में काम नहीं करता है, लेकिन कई सार्वजनिक लिपियों पर अच्छा काम करता है।

यदि आपके पास "नियंत्रण" नामक एक बैश स्क्रिप्ट है और इसके अंदर आपके पास "बिल्ड" नामक एक फ़ंक्शन है:

function build() { 
  ... 
}

तब आप इसे इस तरह से (निर्देशिका में जहां यह है) से कॉल कर सकते हैं:

./control build

यदि यह किसी अन्य फ़ोल्डर के अंदर है, तो वह इसे बना देगा:

another_folder/control build

यदि आपकी फ़ाइल को "control.sh" कहा जाता है, तो यह तदनुसार फ़ंक्शन को इस तरह से कॉल करने योग्य बना देगा:

./control.sh build

1
यह मेरे लिए इंटरैक्टिव खोल में काम नहीं किया। लेकिन इसने काम किया:. ./control.sh && build
saulius2

1

मेरे पास एक ऐसी स्थिति है जहां मुझे बैश स्क्रिप्ट से एक फ़ंक्शन की आवश्यकता होती है जिसे पहले (जैसे द्वारा source) निष्पादित नहीं किया जाना चाहिए और इसके साथ समस्या @$यह है कि myScript.sh तब दो बार चलाया जाता है, ऐसा लगता है ... इसलिए मैं इस विचार के साथ आया हूं समारोह के साथ बाहर निकलने के लिए:

sed -n "/^func ()/,/^}/p" myScript.sh

और इसे उस समय निष्पादित करने के लिए जब मुझे इसकी आवश्यकता होती है, मैं इसे एक फ़ाइल में रखता हूं और उपयोग करता हूं source:

sed -n "/^func ()/,/^}/p" myScript.sh > func.sh; source func.sh; rm func.sh


0

आप कमांड लाइन तर्क से फ़ंक्शन को नीचे की तरह कॉल कर सकते हैं

function irfan() {
echo "Irfan khan"
date
hostname
}
function config() {
ifconfig
echo "hey"
}
$1

एक बार जब आप कार्य समाप्त कर लेते हैं, तो तर्क स्वीकार करने के लिए $ 1 डालते हैं। ऊपर बताएं कि कोड को फन में सहेजा गया है। फ़ंक्शन को चलाने के लिए ।/fun.sh irfan & ./fun.sh config


0

सॉल्व्ड पोस्ट लेकिन मैं अपने पसंदीदा समाधान का उल्लेख करना चाहूंगा। अर्थात्, एक सामान्य एक लाइनर स्क्रिप्ट को परिभाषित करें eval_func.sh:

#!/bin/bash
source $1 && shift && "@a"

फिर किसी भी स्क्रिप्ट के माध्यम से किसी भी फ़ंक्शन को कॉल करें:

./eval_func.sh <any script> <any function> <any args>...

एक मुद्दा जिसे मैं स्वीकृत समाधान के साथ चला रहा हूं वह यह है कि जब मेरे फ़ंक्शन युक्त स्क्रिप्ट को किसी अन्य स्क्रिप्ट के भीतर रखा जाता है, तो उत्तरार्द्ध के तर्कों का मूल्यांकन पूर्व द्वारा किया जाएगा, जिससे त्रुटि हो सकती है।

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