Wbudowane polecenie bash set
, jeśli zostanie wywołane bez argumentów, wyświetli wszystkie zmienne powłoki i środowiska, ale także wszystkie zdefiniowane funkcje. To sprawia, że wyjście jest bezużyteczne dla ludzi i trudne grep
.
Jak mogę sprawić, aby wbudowane polecenie bash wyświetlało set
tylko zmienne, a nie funkcje?
Czy istnieją inne polecenia, które wypisują tylko zmienne powłoki, bez funkcji?
Uwaga: bash rozróżnia zmienne powłoki i zmienne środowiskowe. zobacz tutaj Różnica między zmiennymi środowiskowymi a eksportowanymi zmiennymi środowiskowymi w bash
źródło
_
, których łatwo się pozbyć:(set -o posix ; set | grep -v ^_)
set -o posix; set | sed -e '/^_/,$d'; set +o posix;
(set -o posix; set)
. Bez nawiasów zachowanie bieżącej powłoki Bash zmieniłoby się zgodnie ze standardem Posix. (Nie wiem, co to znaczy, ale wygląda na ważne.) W nawiasach Bash pozostaje niezmieniony.POSIXLY_CORRECT=y
i dodajeposix
do$SHELLOPTS
Oto kilka obejść:
awaria:
declare
wypisuje każdą zdefiniowaną zmienną (eksportowaną lub nie) i funkcję.declare -f
drukuje tylko funkcje.comm -3
usunie wszystkie linie wspólne dla obu. W efekcie spowoduje to usunięcie funkcji, pozostawiając tylko zmienne.Aby wydrukować tylko zmienne, które nie są eksportowane:
Kolejne obejście:
Spowoduje to wydrukowanie tylko zmiennych, ale z pewnymi brzydkimi atrybutami.
Możesz wyciąć atrybuty za pomocą ... cut:
Jednym minusem jest to, że wartość IFS jest interpretowana zamiast wyświetlana.
porównać:
To sprawia, że dość trudno jest użyć tego wyjścia do dalszego przetwarzania, ponieważ jest on samotny
"
w jednej linii. Być może można to zrobić za pomocą IFS-fu, aby temu zapobiec.Jeszcze jedno obejście, używając
compgen
:Wbudowane bash
compgen
miało być używane w skryptach ukończenia. W tym celucompgen -v
wymienia wszystkie zdefiniowane zmienne. Wada: zawiera tylko nazwy zmiennych, a nie wartości.Oto hack, aby również wymienić wartości.
Zaleta: jest to czyste rozwiązanie. Wada: niektóre wartości są pomieszane z powodu interpretacji
printf
. Również podpowłoka z potoku i / lub pętli dodaje dodatkowe zmienne.źródło
declare ...| cut
rura się zepsuje, jeśli nie ma atrybutów dla zmiennej? Zgaduję, że--
w takim przypadku jest to używane, ale nadal jestem niespokojny.sed
może być bezpieczniejszy, tj.declare -p | sed 's/^.* \([^ ]\+\)$/\1/'
compgen
:)typeset
Wbudowane dziwnie posiada opcję, aby pokazać tylko funkcje (-f
), ale nie pokazują tylko parametry. Na szczęścietypeset
(lubset
) wyświetla wszystkie parametry, zanim wszystkie funkcje, nazwy funkcji i parametrów nie mogą zawierać znaków nowej linii lub znaków równości, a znaki nowej linii w wartościach parametrów są cytowane (pojawiają się jako\n
). Możesz więc zatrzymać się w pierwszym wierszu, który nie zawiera znaku równości:Spowoduje to jedynie wydrukowanie nazw parametrów; jeśli chcesz wartości, zmień
print $1
naprint $0
.Zauważ, że drukuje to wszystkie nazwy parametrów (parametry i zmienne są tutaj używane synonimicznie), nie tylko zmienne środowiskowe („zmienna środowiskowa” jest synonimem „eksportowanych parametrów”).
Zauważ również, że zakłada to, że nie ma zmiennej środowiskowej o nazwie, która nie pasuje do ograniczeń bash dotyczących nazw parametrów. Takie zmienne nie mogą być tworzone w bash, ale mogą zostać odziedziczone ze środowiska po uruchomieniu bash:
źródło
set | sed '/=/!Q'
Nie jestem pewien, jak można tworzyć
set
zmienne tylko do drukowania. Jednak patrząc na dane wyjścioweset
, byłem w stanie wymyślić, co wydaje się chwytać tylko zmienne:Zasadniczo szukam linii rozpoczynających się od liter, cyfr lub znaków interpunkcyjnych, po których następuje „=”. Z wyników, które widziałem, pobiera wszystkie zmienne; wątpię jednak, aby było to bardzo przenośne.
Jeśli, jak sugeruje tytuł, chcesz odjąć od tej listy zmienne, które są eksportowane, a tym samym uzyskać listę nieeksportowanych zmiennych, możesz zrobić coś takiego
Aby to nieco rozbić, oto, co robi:
set | grep "^\([[:alnum:]]\|[[:punct:]]\)\+=" | sort > ./setvars
: Mam nadzieję, że pobiera wszystkie zmienne (jak omówiono wcześniej), sortuje je i umieszcza wynik w pliku.&& env | sort
: Po zakończeniu poprzedniego polecenia wywołamyenv
i posortujemy jego wynik.| comm -23 ./setvars -
: Na koniec przesyłamy potokowo posortowane dane wyjścioweenv
docomm
i używamy-23
opcji do drukowania linii unikatowych dla pierwszego argumentu, w tym przypadku linii unikatowych dla naszego wyniku z zestawu.Po zakończeniu możesz wyczyścić plik tymczasowy utworzony za pomocą polecenia
rm ./setvars
źródło
f () {|cat <<EOF|foo=bar|EOF|}
gdzie|
reprezentuje podział wiersza).Wystarczy użyć polecenia
env
. Nie drukuje funkcji.źródło
Spróbuj wykonać polecenie printenv:
źródło
W bash wyświetli tylko nazwy zmiennych:
Lub, jeśli potrzebne są również wartości, użyj:
źródło
różnicowanie się w stosunku do czystej powłoki, aby upewnić się, że pominięto także zmienne skryptów rc
wersja z
comm
byłaby zbyt skomplikowanaźródło
Przyjęta odpowiedź jest świetna. Oferuję alternatywę, która nie wymaga ustawienia trybu POSIX:
Oto technika, której użyłem do przechowywania stanu funkcji w pliku, aby móc kontynuować ją później. Pierwszy tworzy zrzut stanu, a drugi tylko listę nazw zmiennych.
Oba działają przez zrzucanie wierszy, aż znajdzie jeden bez znaku „=”, co występuje, gdy wymieniona jest pierwsza funkcja. Ten ostatni przycina zadanie.
źródło