Mam 2 skrypty powłoki.
Drugi skrypt powłoki zawiera następujące funkcje second.sh
func1
func2
Plik first.sh wywoła drugi skrypt powłoki z pewnymi parametrami i wywoła funkcje func1 i func2 z innymi parametrami specyficznymi dla tej funkcji.
Oto przykład tego, o czym mówię
second.sh
val1=`echo $1`
val2=`echo $2`
function func1 {
fun=`echo $1`
book=`echo $2`
}
function func2 {
fun2=`echo $1`
book2=`echo $2`
}
first.sh
second.sh cricket football
func1 love horror
func2 ball mystery
Jak mogę to osiągnąć?
v=$(echo $1)
jest całkowicie zbędny. Po prostu napiszfun2=$1
. Jedyna różnica polega na tym, że$()
(lub lewy apostrof) usuwają końcowe znaki nowej linii.Odpowiedzi:
Refaktoryzuj swój
second.sh
skrypt w ten sposób:function func1 { fun=$1 book=$2 printf "fun=%s,book=%s\n" "${fun}" "${book}" } function func2 { fun2=$1 book2=$2 printf "fun2=%s,book2=%s\n" "${fun2}" "${book2}" }
Następnie wywołaj te funkcje ze skryptu w
first.sh
następujący sposób:source ./second.sh func1 love horror func2 ball mystery
WYNIK:
źródło
source
polecenie faktycznie uruchomi skrypt przekazany jako argument.Nie możesz bezpośrednio wywołać funkcji w innym skrypcie powłoki.
Możesz przenieść definicje funkcji do oddzielnego pliku, a następnie załadować je do skryptu za pomocą
.
polecenia, na przykład:Będzie to interpretowane
functions.sh
tak, jakby w tym momencie zawartość była faktycznie obecna w pliku. Jest to powszechny mechanizm implementacji współdzielonych bibliotek funkcji powłoki.źródło
.
jest to alias dlasource
?source
jest aliasem dla.
, nie zawsze tak jest. Na przykładdash
pakiet na Debianie, który zapewnia/bin/sh
, nie masource
polecenia.source
polecenie nie działało w Ubuntu @ajsharma. Odniesienie: nie znaleziono polecenia źródła w powłoce shProblem
Obecnie akceptowana odpowiedź działa tylko pod ważnymi warunkami. Dany...
/foo/bar/first.sh
:function func1 { echo "Hello $1" }
i
/foo/bar/second.sh
:#!/bin/bash source ./first.sh func1 World
działa to tylko wtedy, gdy
first.sh
jest wykonywany z tego samego katalogu, w którymfirst.sh
znajduje się. To znaczy. jeśli bieżącą ścieżką roboczą powłoki jest/foo
, próba uruchomienia poleceniacd /foo ./bar/second.sh
błąd wydruków:
/foo/bar/second.sh: line 4: func1: command not found
Dzieje się tak, ponieważ
source ./first.sh
jest on względny w stosunku do bieżącej ścieżki roboczej, a nie ścieżki do skryptu. Stąd jednym rozwiązaniem może być użycie podpowłoki i uruchomienie(cd /foo/bar; ./second.sh)
Bardziej ogólne rozwiązanie
Dany...
/foo/bar/first.sh
:function func1 { echo "Hello $1" }
i
/foo/bar/second.sh
:#!/bin/bash source $(dirname "$0")/first.sh func1 World
następnie
cd /foo ./bar/second.sh
wydruki
Jak to działa
$0
zwraca względną lub bezwzględną ścieżkę do wykonywanego skryptudirname
zwraca ścieżkę względną do katalogu, w którym istnieje skrypt $ 0$( dirname "$0" )
dirname "$0"
polecenie zwraca ścieżkę względną do katalogu wykonywanego skryptu, który jest następnie wykorzystywany jako argument dlasource
komendy/first.sh
po prostu dodaje nazwę zaimportowanego skryptu powłokisource
ładuje zawartość określonego pliku do bieżącej powłokiźródło
Jeśli zdefiniujesz
#!/bin/bash fun1(){ echo "Fun1 from file1 $1" } fun1 Hello . file2 fun1 Hello exit 0
w plik1 (chmod 750 plik1) i plik2
fun1(){ echo "Fun1 from file2 $1" } fun2(){ echo "Fun1 from file1 $1" }
i uruchom ./file2 otrzymasz Fun1 z pliku1 Hello Fun1 z pliku2 Hello Surprise !!! Zastępujesz fun1 w pliku1 przez fun1 z pliku2 ... Aby tego nie robić, musisz
declare -f pr_fun1=$fun1 . file2 unset -f fun1 fun1=$pr_fun1 unset -f pr_fun1 fun1 Hello
zapisuje twoją poprzednią definicję dla fun1 i przywraca ją z poprzednią nazwą, usuwając niepotrzebną zaimportowaną. Za każdym razem, gdy importujesz funkcje z innego pliku, możesz pamiętać dwa aspekty:
źródło
#vi function.sh #!/bin/bash f1() { echo "Hello $name" } f2() { echo "Enter your name: " read name f1 } f2 #sh function.sh
Tutaj funkcja
f2
wywoła funkcjęf1
źródło