Odpowiedzi:
Jeśli skrypt definiuje tylko funkcje i nie robi nic więcej, możesz najpierw wykonać skrypt w kontekście bieżącej powłoki za pomocą polecenia source
lub, .
a następnie po prostu wywołać funkcję. Zobacz, help source
aby uzyskać więcej informacji.
bash
) i exit
zakończy ona tylko podpowłokę, ale nie zakończy swojego terminala.
Cóż, podczas gdy inne odpowiedzi są prawidłowe - z pewnością możesz zrobić coś innego: jeśli masz dostęp do skryptu bash, możesz go zmodyfikować i po prostu umieścić na końcu specjalny parametr "$@"
- który rozwinie się do argumentów wiersza poleceń określasz, a ponieważ jest „sam”, powłoka będzie próbowała nazywać je dosłownie; i tutaj możesz określić nazwę funkcji jako pierwszy argument. Przykład:
$ 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
W przypadku języka polskiego możesz najpierw sprawdzić, czy polecenie istnieje i jest funkcją:
# 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
"$@"
w większości przypadków. $@
w niektórych przypadkach nie jest bezpieczne.
bash test.sh testA testB
?
[ ! -z "$1" ]
przeciwnym razie source podniesie instrukcję else w niektórych
Następujące polecenie najpierw rejestruje funkcję w kontekście, a następnie ją wywołuje:
. ./myScript.sh && function_name
Krótko mówiąc, nie.
Możesz zaimportować wszystkie funkcje skryptu do swojego środowiska za pomocą source
( help source
aby uzyskać szczegółowe informacje), co pozwoli ci na ich wywołanie. Ma to również wpływ na wykonanie skryptu, więc uważaj.
Nie ma możliwości wywołania funkcji ze skryptu powłoki tak, jakby była to biblioteka współdzielona.
Za pomocą 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
Ten skrypt uruchomi funkcje fun1 i fun2, ale jeśli uruchomisz go z opcją fun1 lub fun2, uruchomi tylko daną funkcję z argumentami (jeśli są podane) i zakończy działanie. Stosowanie
$ ./test
run function1
run function2
$ ./test fun2 a b c
run function2
options: a b c
Edycja: OSTRZEŻENIE - wydaje się, że to nie działa we wszystkich przypadkach, ale działa dobrze w wielu publicznych skryptach.
Jeśli masz skrypt basha o nazwie „control”, a wewnątrz niego znajduje się funkcja o nazwie „build”:
function build() {
...
}
Następnie możesz nazwać to w ten sposób (z katalogu, w którym się znajduje):
./control build
Jeśli znajduje się w innym folderze, oznaczałoby to:
another_folder/control build
Jeśli twój plik nazywa się „control.sh”, to odpowiednio sprawi, że funkcja będzie wywoływana w następujący sposób:
./control.sh build
. ./control.sh && build
Mam sytuację, w której potrzebuję funkcji ze skryptu basha, której wcześniej nie można wykonać (np. Przez source
) i problem @$
polega na tym, że myScript.sh jest wtedy uruchamiany dwukrotnie, wydaje się ... Więc wpadłem na pomysł aby uzyskać funkcję za pomocą seda:
sed -n "/^func ()/,/^}/p" myScript.sh
Aby wykonać to w momencie, w którym go potrzebuję, umieszczam go w pliku i używam source
:
sed -n "/^func ()/,/^}/p" myScript.sh > func.sh; source func.sh; rm func.sh
możesz wywołać funkcję z argumentu wiersza poleceń, jak poniżej
function irfan() {
echo "Irfan khan"
date
hostname
}
function config() {
ifconfig
echo "hey"
}
$1
Po zakończeniu funkcji wstaw $ 1, aby zaakceptować argument, powiedzmy, że powyższy kod zostanie zapisany w fun.sh, aby uruchomić funkcję ./fun.sh irfan & ./fun.sh config
Post rozwiązany, ale chciałbym wspomnieć o moim preferowanym rozwiązaniu. Mianowicie zdefiniuj ogólny jednoliniowy skrypt eval_func.sh
:
#!/bin/bash
source $1 && shift && "@a"
Następnie wywołaj dowolną funkcję w dowolnym skrypcie poprzez:
./eval_func.sh <any script> <any function> <any args>...
Problem, na który natknąłem się przy przyjętym rozwiązaniu, polega na tym, że podczas pozyskiwania mojego skryptu zawierającego funkcję w innym skrypcie argumenty tego drugiego byłyby oceniane przez ten pierwszy, powodując błąd.
exit
w swojej funkcji, zamknie ona terminal po wykonaniu funkcji. Czy można to obejść? @SvenMarnach