Ответы:
Если сценарий только определяет функции и больше ничего не делает, вы можете сначала выполнить сценарий в контексте текущей оболочки с помощью команды source
или, .
а затем просто вызвать функцию. См. help source
Дополнительную информацию.
bash
) и exit
завершите только подоболочку, но не ваш терминал.
Что ж, в то время как другие ответы верны - вы, безусловно, можете сделать что-то еще: если у вас есть доступ к сценарию bash, вы можете его изменить и просто поместить в конце специальный параметр, "$@"
который будет расширяться до аргументов командной строки вы указываете, и, поскольку он "один", оболочка попытается вызвать их дословно; и здесь вы можете указать имя функции в качестве первого аргумента. Пример:
$ 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
"$@"
в большинстве случаев. $@
в некоторых случаях небезопасно.
bash test.sh testA testB
?
[ ! -z "$1" ]
иначе источник вызовет оператор else в некоторых версиях bash
Следующая команда сначала регистрирует функцию в контексте, а затем вызывает ее:
. ./myScript.sh && function_name
Короче нет.
Вы можете импортировать все функции сценария в свою среду с помощью source
( help source
для подробностей), что затем позволит вам их вызывать. Это также имеет эффект выполнения сценария, так что будьте осторожны.
Невозможно вызвать функцию из сценария оболочки, как если бы это была общая библиотека.
С помощью 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
Этот сценарий будет запускать функции fun1 и fun2, но если вы запустите его с опцией fun1 или fun2, он запустит только заданную функцию с аргументами (если предоставлен) и завершится. использование
$ ./test
run function1
run function2
$ ./test fun2 a b c
run function2
options: a b c
Изменить: ПРЕДУПРЕЖДЕНИЕ - похоже, это работает не во всех случаях, но хорошо работает во многих общедоступных скриптах.
Если у вас есть сценарий bash под названием «control», а внутри него есть функция под названием «build»:
function build() {
...
}
Затем вы можете вызвать его так (из каталога, в котором он находится):
./control build
Если он находится внутри другой папки, это будет:
another_folder/control build
Если ваш файл называется «control.sh», это соответственно сделает функцию вызываемой следующим образом:
./control.sh build
. ./control.sh && build
У меня есть ситуация, когда мне нужна функция из сценария bash, который не должен выполняться раньше (например, source
), и проблема в @$
том, что myScript.sh затем запускается дважды, кажется ... Итак, я пришел к идее чтобы получить функцию с помощью sed:
sed -n "/^func ()/,/^}/p" myScript.sh
И чтобы выполнить его в нужное время, я помещаю его в файл и использую source
:
sed -n "/^func ()/,/^}/p" myScript.sh > func.sh; source func.sh; rm func.sh
вы можете вызвать функцию из аргумента командной строки, как показано ниже
function irfan() {
echo "Irfan khan"
date
hostname
}
function config() {
ifconfig
echo "hey"
}
$1
как только вы завершите функцию, поместите $ 1 для принятия аргумента, скажем, приведенный выше код сохранен в fun.sh для запуска функции ./fun.sh irfan & ./fun.sh config
Решенный пост, но я хотел бы упомянуть свое предпочтительное решение. А именно, определите общий однострочный сценарий eval_func.sh
:
#!/bin/bash
source $1 && shift && "@a"
Затем вызовите любую функцию в любом скрипте через:
./eval_func.sh <any script> <any function> <any args>...
Проблема, с которой я столкнулся с принятым решением, заключается в том, что при поиске моего скрипта, содержащего функцию, в другом скрипте, аргументы последнего будут оцениваться первым, вызывая ошибку.
exit
в своей функции, он закроет терминал после выполнения функции. Есть ли способ обойти это? @SvenMarnach