W moim skrypcie w bashu jest dużo zmiennych i muszę coś zrobić, aby zapisać je do pliku. Moje pytanie brzmi, jak wyświetlić wszystkie zmienne zadeklarowane w moim skrypcie i uzyskać taką listę:
VARIABLE1=abc
VARIABLE2=def
VARIABLE3=ghi
set
wypisze zmienne, niestety wypisze również definicje funkcji.
Na szczęście tryb POSIX wyświetla tylko zmienne:
( set -o posix ; set ) | less
Piping do less
lub przekierowanie do miejsca, w którym chcesz mieć opcje.
Aby uzyskać zmienne zadeklarowane tylko w skrypcie:
( set -o posix ; set ) >/tmp/variables.before
source script
( set -o posix ; set ) >/tmp/variables.after
diff /tmp/variables.before /tmp/variables.after
rm /tmp/variables.before /tmp/variables.after
(A przynajmniej coś na tej podstawie :-))
-o posix
różnicą now a będzie zawierało tylko zmienne.VARS="`set -o posix ; set`"; source script; SCRIPT_VARS="`grep -vFe "$VARS" <<<"$(set -o posix ; set)" | grep -v ^VARS=`"; unset VARS;
. Spowoduje to również wyświetlenie zmiennych w formacie gotowym do zapisania. Lista będzie zawierała zmienne, które zmienił skrypt (zależy od tego, czy jest to pożądane)source
, powinieneś móc to zrobić z wyjściemdeclare -p
.before=$(set -o posix; set); dosomestuff; diff <(echo "$before") <(set -o posix; set)
Zawiera listę wszystkich zmiennych, w tym lokalnych. Nauczyłem się tego z listy zmiennych Get, których nazwa pasuje do określonego wzorca , i użyłem go w moim skrypcie .
źródło
compgen -v
wymienia również zmienne globalne, które nie były ustawione lokalnie. Nie jestem pewien, czy to długotrwały błąd, czy pożądane zachowanie.To musi wypisać wszystkie nazwy zmiennych powłoki. Możesz otrzymać listę przed i po pobraniu pliku, tak jak przy „ustawieniu”, aby porównać, które zmienne są nowe (jak wyjaśniono w innych odpowiedziach). Pamiętaj jednak, że takie filtrowanie za pomocą diff może odfiltrować niektóre zmienne, których potrzebujesz, ale były obecne przed pozyskaniem pliku.
W Twoim przypadku, jeśli wiesz, że nazwy Twoich zmiennych zaczynają się od „VARIABLE”, możesz pobrać skrypt i wykonać:
UPDATE: Dla czystego rozwiązania BASH (bez zewnętrznych poleceń):
źródło
eval "printf '%q\n' $(printf ' "${!%s@}"' _ {a..z} {A..Z})"
Na podstawie niektórych z powyższych odpowiedzi, to zadziałało dla mnie:
plik źródłowy :
źródło
Jeśli możesz postprocesować (jak już wspomniano), możesz po prostu
set
wywołać na początku i na końcu swojego skryptu (każdy do innego pliku) i zrobić różnicę na dwóch plikach. Zrozum, że nadal będzie zawierał trochę hałasu.Możesz to również zrobić programowo. Aby ograniczyć dane wyjściowe tylko do bieżącego zakresu, należałoby zaimplementować opakowanie do tworzenia zmiennych. Na przykład
Co daje
źródło
Oto coś podobnego do odpowiedzi @GinkgoFr, ale bez problemów zidentyfikowanych przez @Tino lub @DejayClayton i jest bardziej wytrzymałe niż sprytny
set -o posix
kawałek @ DouglasLeeder :Różnica polega na tym, że to rozwiązanie zatrzymuje się po pierwszym niezmiennym raporcie, np. Pierwszej funkcji zgłoszonej przez
set
BTW: Problem „Tino” został rozwiązany. Mimo że POSIX jest wyłączony, a funkcje są raportowane przez
set
,sed ...
część rozwiązania zezwala tylko na raportowanie zmiennych (np.VAR=VALUE
Wiersze). W szczególności,A2
czy nie fałszywie uczynić go do wyjścia.AND: Problem „DejayClayton” został rozwiązany (osadzone znaki nowej linii w wartościach zmiennych nie zakłócają wyjścia - każdy z nich
VAR=VALUE
otrzymuje jedną linię wyjściową):UWAGA: Rozwiązanie dostarczone przez @DouglasLeeder cierpi na problem „DejayClayton” (wartości z osadzonymi znakami nowej linii). Poniżej
A1
jest błędne iA2
nie powinno się w ogóle wyświetlać.WRESZCIE: nie sądzę, że wersja ma
bash
znaczenie, ale może. Testowałem / rozwijałem na tym:POST-SCRIPT: Biorąc pod uwagę niektóre inne odpowiedzi na OP, mam <100% pewności, że
set
zawsze konwertuje znaki nowej linii w wartości\n
, na której opiera się to rozwiązanie, aby uniknąć problemu „DejayClayton”. Może to nowoczesne zachowanie? A może zmiana w czasie kompilacji? Lub ustawienie opcjiset -o
lubshopt
? Jeżeli ty wiesz o takich zmian, należy dodać komentarz ...źródło
Spróbuj użyć skryptu (nazwijmy go „ls_vars”):
chmod + x it i:
źródło
Z punktu widzenia bezpieczeństwa, zarówno na @ akostadinov odpowiedź lub @ JuvenXu na odpowiedź korzystne jest poleganie na niestrukturalnych wyjściu
set
polecenia, ze względu na następujące potencjalne luki bezpieczeństwa:Powyższa funkcja
doLogic
służyset
do sprawdzania obecności zmiennej wPS1
celu określenia, czy skrypt jest interaktywny, czy nie (nieważne, czy jest to najlepszy sposób na osiągnięcie tego celu; to tylko przykład).Jednak wynik
set
jest nieustrukturyzowany, co oznacza, że każda zmienna zawierająca znak nowej linii może całkowicie zanieczyścić wyniki.Jest to oczywiście potencjalne zagrożenie bezpieczeństwa. Zamiast tego użyj obsługi Bash do pośredniego rozwijania nazw zmiennych lub
compgen -v
.źródło
Spróbuj tego:
set | egrep "^\w+="
(z| less
orurowaniem lub bez )Pierwsze proponowane rozwiązanie
( set -o posix ; set ) | less
działa, ale ma wadę: przekazuje kody sterujące do terminala, więc nie są one poprawnie wyświetlane. Tak na przykład, jeśli jest (prawdopodobnie)IFS=$' \t\n'
zmienna, możemy zobaczyć:…zamiast.
Moje
egrep
rozwiązanie wyświetla to (i ewentualnie inne podobne) poprawnie.źródło
bash -c $'a() { echo "\nA=B"; }; unset A; set | egrep "^\w+="' | grep ^A
wyświetlaczeA=B"
-> Niepowodzenie!Prawdopodobnie ukradłem odpowiedź jakiś czas temu ... w każdym razie trochę inaczej jako func:
źródło
printenv
Polecenie:printenv
wypisuje wszystkoenvironment variables
wraz z ich wartościami.Powodzenia...
źródło
Prostym sposobem na to jest użycie trybu ścisłego bash poprzez ustawienie zmiennych środowiskowych systemu przed uruchomieniem skryptu i użycie diff do sortowania tylko tych w skrypcie:
Możesz teraz pobrać zmienne swojego skryptu w /tmp/script_vars.log. A przynajmniej coś opartego na tym!
źródło
Trochę za późno na imprezę, ale oto kolejna sugestia:
Różn + sed Linia komend rurociąg wysyła wszystkie zmienne skryptów zdefiniowane w żądanym formacie (jak określono na stanowiskach w OP)
źródło