Całkowicie odpowiedziałem na twoje pytanie, ale mam nadzieję, że jest to pomocne. Dotknąłem kilku ogólnych rzeczy, a następnie szczegółów na temat domyślnej bramy i wreszcie innych przykładów.
Oto kilka ogólnych komentarzy:
Sugeruję, aby utworzyć te wywołania w funkcje, które między innymi pozwolą ci zbudować swoje funkcje tak, aby funkcje wyższego poziomu mogły po prostu owijać wokół jednej lub więcej funkcji niższego poziomu.
Do obsługi danych wyjściowych z funkcji uważam, że użycie stdout jest najbardziej uniwersalną metodą i nadaje się do modułowego podejścia do tworzenia funkcji.
Jeśli wykonasz przypisanie zmiennych i wyeksportujesz z funkcji, problemy z zakresem spowodują problemy.
Jeśli masz funkcję, która przypisuje się do zmiennej wewnątrz tej samej funkcji; na przykład
`testFx() { export routeInfo="$(route)"; }`
Jeśli przypisanie zmiennej do routeInfo przez „testFx” ma taki sam zakres jak wywołujący - innymi słowy, jeśli funkcja jest zadeklarowana w bieżącej powłoce i wywołana z bieżącej powłoki, wynikowe przypisanie do zmiennej routeInfo będzie dostępne z tego muszla. Jeśli funkcja zostanie użyta w wykonanym skrypcie, wynik nie będzie dostępny dla powłoki, która wywołała skrypt, chociaż funkcja będzie dostępna.
Jest to trochę nadmierne uproszczenie, ale myślę, że dobrze wyjaśnia problem zakresu. Obiekty w zakresie dla rodzica są dostępne dla potomnej powłoki / procesu, ale nie odwrotnie. Trudno jest przekazać rzeczy „z powrotem” do linii (w skrócie).
Ta różnica ujawnia się w różnych zachowaniach obserwowanych podczas pozyskiwania pliku skryptu w porównaniu do wykonywania pliku skryptu.
Wykonany skrypt działa w powłoce podrzędnej / podrzędnej; plik źródłowy jest dodawany do środowiska lokalnego w bieżącym kontekście; nie w podrzędnej / podrzędnej powłoce.
Możesz przetestować to, co mówię, dodając tę prostą funkcję do swojej powłoki - po prostu wklej ją (lub dodaj do .bashrc i załaduj ponownie powłokę itp.)
Następnie wywołać funkcję i spróbować echo zmiennej gospodarstwa wartości echo $routeInfo
. To zadziała zgodnie z oczekiwaniami.
Wyczyść tę zmienną za pomocą unset routeInfo
Następnie utwórz prosty skrypt w następujący sposób:
vi ~/test.sh
z zawartością:
#!/bin/bash
testFx
Zapisz, zamknij i dodaj uprawnienia do wykonywania chmod +x ~/test.sh
Następnie uruchom skrypt ~/test.sh
z powłoki, w której jest zdefiniowana ta funkcja.
Po uruchomieniu skryptu wywołaj echo zmiennej, która powinna zawierać wartość echo $routeInfo
:, a zobaczysz, że jest pusta - zakładając, że wykonałeś wywołanie unset powyżej; ponieważ eksport nie mógł przejść do nadrzędnej powłoki / procesu.
Z powodu tego problemu z zasięgiem i braku tradycyjnej wartości „return” z funkcji bash, sposób, w jaki zazwyczaj widzę wartość „wynik” z użytej funkcji bash, jest albo bezpośredni; przez pozostawienie wyjścia na standardowym wyjściu lub przechwycenie go w zmiennej. W obu przypadkach sama funkcja jest zapisywana w ten sam sposób, zmienia się tylko sposób jej wywołania.
Oto kilka przykładów „pobierania” wartości wyjściowych z funkcji bash
rslt=$(testFx)
Jeżeli można spodziewać się wiele wyników można zachować wyniki w tablicy:
rslt=($(testFx))
z ${#rslt[@]}
zawierający liczbę pozycji (n), można uzyskać dostęp do elementów albo poprzez bezpośrednie indeksowania:
${rslt[$a]}
z = 0 do N-1,
lub za pomocą pętli:
for i in ${rslt[@]}; do echo "$i"; done
Mam nadzieję, że to rozwiązało dużą część twojego pytania. Wrzucam kilka funkcji gromadzenia danych w sieci, które mam na moim komputerze lokalnym. Jeśli szukasz jakiejś konkretnej informacji, daj mi znać, prawdopodobnie mam do tego funkcję.
getExternalIP () {
lynx -dump -hiddenlinks=ignore -nolist http://checkip.dyndns.org:8245/ | grep "Current IP Address" | cut -d":" -f2 | cut -d" " -f2
}
getLanIP () {
ip addr show | grep -E -v '127\.0' | grep -Eo '^.*brd' | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
}
getDefGW_IP () {
route -n | awk '/UG/ {print $2}';
}
getDefGW_Host () {
route | awk '/default/ {print $2}';
}
getDefGW_Host_and_IP () {
echo "Def. GW hostname / IP Address: $(getDefGW_Host) / $(getDefGW_IP)";
}
Oto przydatny ciąg wyrażeń regularnych do użycia podczas pracy z adresami IP:
iprgx='(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'
Przykład użycia tej funkcji - funkcja wyświetlająca wszystkie adresy IP w twojej sieci LAN, z których widziałeś pakiety ARP:
getARPTable_IPs() {
arp -na | grep -Eo "$iprgx";
}
Przechowuj wyniki w tablicy:
arpIPs=($(getARPTable_IPs))
Na koniec, dla nowoczesnej dystrybucji Linuksa, oto polecenia i lokalizacje systemu plików, których często używam, aby uzyskać informacje / status sieci. Starsze polecenia, takie jak netstat i ifconfig, są przestarzałe i nie bez powodu.
- ip
- ss
- W katalogu / sys / class / net będzie katalog dla każdej karty sieciowej w systemie wypełniony plikami zawierającymi informacje o sieci.
za. Wiele narzędzi wiersza poleceń po prostu korzysta z tych danych wyjściowych i ponownie je formatuje.
b. / proc / net ma wiele informacji.
do. Na przykład arp -na
polecenie może być całkowicie zreplikowane przezcat /proc/net/arp
- iptables