Respostas:
Se o script apenas definir as funções e não fizer mais nada, você pode primeiro executar o script dentro do contexto do shell atual usando o comando source
ou .
e, em seguida, simplesmente chamar a função. Veja help source
para mais informações.
bash
) e exit
só encerrará o subshell, mas não seu terminal.
Bem, enquanto as outras respostas estão certas - você certamente pode fazer outra coisa: se você tiver acesso ao script bash, você pode modificá-lo e simplesmente colocar no final o parâmetro especial "$@"
- que se expandirá para os argumentos da linha de comando você especifica e, como está "sozinho", o shell tentará chamá-los literalmente; e aqui você pode especificar o nome da função como o primeiro argumento. Exemplo:
$ 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
Para polir, você pode primeiro verificar se o comando existe e é uma função:
# 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
"$@"
na maioria dos casos. $@
não é seguro em alguns casos.
bash test.sh testA testB
?
[ ! -z "$1" ]
caso contrário, a fonte levantará a instrução else em algumas
O comando a seguir primeiro registra a função no contexto e a chama:
. ./myScript.sh && function_name
Resumidamente, não.
Você pode importar todas as funções do script para o seu ambiente com source
( help source
para obter detalhes), o que permitirá que você as chame. Isso também tem o efeito de executar o script, portanto, tome cuidado.
Não há como chamar uma função de um script de shell como se fosse uma biblioteca compartilhada.
Usando 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
Este script executará as funções fun1 e fun2, mas se você iniciá-lo com a opção fun1 ou fun2, ele apenas executará a função dada com args (se fornecida) e sairá. Uso
$ ./test
run function1
run function2
$ ./test fun2 a b c
run function2
options: a b c
Editar: AVISO - parece que isso não funciona em todos os casos, mas funciona bem em muitos scripts públicos.
Se você tem um script bash chamado "control" e dentro dele você tem uma função chamada "build":
function build() {
...
}
Então você pode chamá-lo assim (do diretório onde está):
./control build
Se estiver dentro de outra pasta, isso o tornaria:
another_folder/control build
Se o seu arquivo for chamado "control.sh", isso tornaria a função chamável assim:
./control.sh build
. ./control.sh && build
Tenho uma situação em que preciso de uma função do script bash que não deve ser executada antes (por exemplo, por source
) e o problema @$
é que myScript.sh é executado duas vezes, parece ... Então, tive a ideia para obter a função com sed:
sed -n "/^func ()/,/^}/p" myScript.sh
E para executá-lo na hora que preciso, coloco em um arquivo e uso source
:
sed -n "/^func ()/,/^}/p" myScript.sh > func.sh; source func.sh; rm func.sh
você pode chamar a função a partir do argumento da linha de comando como abaixo
function irfan() {
echo "Irfan khan"
date
hostname
}
function config() {
ifconfig
echo "hey"
}
$1
assim que a função end coloque $ 1 para aceitar o argumento, digamos que o código acima seja salvo em fun.sh para executar a função ./fun.sh irfan & ./fun.sh config
Postagem resolvida, mas gostaria de mencionar minha solução preferida. Ou seja, defina um script genérico de uma linha eval_func.sh
:
#!/bin/bash
source $1 && shift && "@a"
Em seguida, chame qualquer função em qualquer script por meio de:
./eval_func.sh <any script> <any function> <any args>...
Um problema que encontrei com a solução aceita é que, ao buscar meu script que contém a função em outro script, os argumentos do último seriam avaliados pelo primeiro, causando um erro.
exit
em sua função, ele fechará o terminal após a execução da função. Existe alguma maneira de contornar isso? @SvenMarnach