source some_file
jakiś plik:
doit ()
{
echo doit $1
}
export TEST=true
Jeśli podam jakiś plik, funkcja „doit” i zmienna TEST są dostępne w wierszu poleceń. Ale uruchomienie tego skryptu:
script.sh:
#/bin/sh
echo $TEST
doit test2
Zwróci wartość TEST, ale wygeneruje błąd dotyczący nieznanej funkcji „doit”.
Czy mogę również „wyeksportować” tę funkcję, czy też muszę pobrać plik_pliku w script.sh, aby użyć tej funkcji?
#!/bin/sh
na#!/bin/bash
i podoit() {...}
prostuexport -f doit
#!/bin/sh
, ale dobrą praktyką jest używanie go#!/bin/bash
, aby uniknąć problemów, gdy domyślna powłoka nie jest bash.Odpowiedzi:
W Bash możesz eksportować definicje funkcji do podpowłoki za pomocą
Na przykład możesz wypróbować ten prosty przykład:
./script1
:./script2
:Jeśli zadzwonisz
./script1
, zobaczysz wynik Hello! .źródło
„Eksportowanie” funkcji za pomocą
export -f
tworzy zmienną środowiskową z treścią funkcji. Rozważ ten przykład:Oznacza to, że tylko powłoka (tylko Bash?) Będzie mogła zaakceptować tę funkcję. Możesz także ustawić tę funkcję samodzielnie, ponieważ Bash bierze pod uwagę envvary zaczynające się od
() {
jako:Jeśli potrzebujesz „wyeksportować” tę zmienną przez SSH, to naprawdę potrzebujesz tej funkcji jako łańcucha. Można to zrobić za pomocą opcji drukowania (
-p
) dla funkcji (-f
)declare
wbudowanego:Jest to bardzo przydatne, jeśli masz bardziej złożony kod, który należy wykonać przez SSH. Rozważ następujący fikcyjny skrypt:
źródło
fn2='() { echo Hi;}' sh -c fn2
nie działało dla mnie. Na arch Linux zsh
bash v5.0.7 mamsh: fn2: command not found
. Na Ubuntu zsh
byciem dash v0.2.3 mamsh: 1: fn2: not found
. Z którejsh
powłoki korzystałeś?f(){ echo a;}; export -f f; echo "$f"; sh -c 'printenv f; echo "$f"'
nic dla mnie nie drukuje, więc najwyraźniejf
nie jest eksportowany jako zwykły ciąg. Testowałem z obydwoma wyżej wymienionymi kombinacjami.sh
wykonywać ten ciąg jako funkcję? W twoim przykładzie podanefn2='() { echo Hi;}' sh -c fn2
polecenie jest dosłownie ciągiem . powinien szukać takiej komendy w PATH, ale nie powinien sprawdzać, czy istnieje zmienna , rozwijać tę zmienną i wykonywać jej wartość jako funkcję - brzmi to dla mnie poważnie. edycja: Myślę, że to wszystko! Czy pokazane zachowanie było błędem bezpieczeństwa znanym jako ShellShock / Bashdoor ?fn2
sh
"fn2"
sh
$fn2
fn(){ echo foo; }; export -f fn; env | grep foo
wynikiBASH_FUNC_fn%%=() { echo foo
Opierając się na odpowiedzi @ Lekensteyn ...
Jeśli
declare -pf
go użyjesz , wyświetli wszystkie poprzednio zdefiniowane funkcje w bieżącej powłoce do STDOUT.W tym momencie możesz przekierować STDOUT tam, gdzie chcesz i w efekcie wstawić wcześniej zdefiniowane funkcje w dowolne miejsce.
Poniższa odpowiedź umieści je w zmiennej. Następnie echo tej zmiennej plus wywołanie funkcji, którą chcemy uruchomić w nowej powłoce, która jest spawnowana jako nowy użytkownik. Robimy to za pomocą
sudo
przełącznika-u
(aka.user
) I po prostu uruchamiając Bash (który otrzyma potokowy STDOUT jako dane wejściowe do uruchomienia).Ponieważ wiemy, że przechodzimy z powłoki Bash do powłoki Bash, wiemy, że Bash poprawnie interpretuje funkcje zdefiniowane przez poprzednie powłoki. Składnia powinna być poprawna, o ile przechodzimy między jedną powłoką Bash tej samej wersji do nowej powłoki Bash tej samej wersji.
YMMV, jeśli poruszasz się między różnymi powłokami lub między systemami, które mogą mieć różne wersje Bash.
źródło
Nie można eksportować funkcji, nie w sposób, który opisuje. Powłoka załaduje
~/.bashrc
plik tylko na początku interaktywnej powłoki (wyszukaj „Invocation” na stronie podręcznika bash ).Co możesz zrobić, to utworzyć „bibliotekę”, która jest ładowana podczas uruchamiania programu:
I umieść tam swoje nieinteraktywne funkcje i ustawienia.
źródło
BASH_ENV
zmienną środowiskową,some_file
którą już masz, i zostanie wywołana. Łatwo byłoby się tego dowiedzieć:echo echo foobar > /tmp/foobar; BASH_ENV=/tmp/foobar $SHELL -c :
eval "$(declare -F | sed -e 's/-f /-fx /')"
wyeksportuje wszystkie funkcje.Robię to dużo przed uruchomieniem interaktywnej powłoki w skrypcie, aby umożliwić mi debugowanie i pracę w kontekście skryptu przy użyciu jego funkcji i zmiennych.
Przykład:
źródło
Funkcje nie są eksportowane do podprocesów. Dlatego istnieją pliki o nazwach .kshrc lub .bashrc: Aby zdefiniować funkcje, które powinny być dostępne również w podpowłokach.
W przypadku uruchamiania skryptu skrypty. * Shrc zwykle nie są pozyskiwane. Będziesz musiał to jawnie zakodować, tak jak w
. ~/.kshrc
.źródło
rm=rm -i
)Cóż, jestem nowy w Linuksie, ale możesz spróbować. W jakimś pliku nazwijmy go „tmp / general”, budujesz swoją funkcję:
W skrypcie powłoki dodaj:
i biegnij:
Dostaniesz na ekranie:
func from general
.źródło
Więcej informacji
źródło