W jaki sposób mogę wydrukować listę aktualnie zdefiniowanych zmiennych środowiskowych bez ich wartości w sposób zgodny z posix, który działa z wieloma implementacjami ?
W niektórych implementacjach (mksh, freebsd / bin / sh), samo użycie export
będzie pasować do rachunku:
$ export
FOO2
FOO
Ale w przypadku niektórych innych implementacji (bash, zsh, dash) export
również pokazuje wartość. Z bash na przykład:
$ export
export FOO2='as df\
asdk=fja:\
asd=fa\
asdf'
export FOO='sjfkasjfd kjasdf:\
asdkj=fkajdsf:\
:askjfkajsf=asdfkj:\
safdkj'
$ printenv | sed -n l
FOO2=as\tdf\$
asdk=fja:\$
asd=fa\$
asdf$
FOO=sjfkasjfd kjasdf:\$
asdkj=fkajdsf:\$
\t:askjfkajsf=asdfkj:\$
safdkj$
Inne opcje, takie jak env
lub printenv
nie mają możliwości, aby wydrukować tylko nazwy zmiennych bez wartości, a przynajmniej nie na platformach Linux i FreeBSD próbowałem.
Przesyłanie strumieniowe do awk / sed / etc. lub przycinanie listy za pomocą technik rozszerzania parametrów (np. ${foo%%=*}
) jest dopuszczalne, ale musi współpracować z wartościami, które mogą obejmować linie i zawierać =
oraz spacje w wartości (patrz przykład powyżej).
Odpowiedzi dotyczące konkretnych implementacji powłoki są interesujące, ale przede wszystkim szukam czegoś, co będzie kompatybilne z różnymi implementacjami.
export -p
określonym przez POSIX, aby wygenerować wyjście, które jest również odpowiednie dla danych wejściowych w powłoce.export -p
?export -p
ponieważ dałoby to spójny wynik we wszystkich powłokach POSIX, co powiedziałeś, że chcesz.export -p
nie spełnia pierwszego wymagania - wypisuje tylko nazwy zmiennych bez wartości.export -p
. Nie zamierzam pisać tego parsowania, ponieważ w ogólnym przypadku musiałoby to również wykonać prawidłowe parsowanie cytatów, na wypadek gdybyś miał zmienną, której wartość jest podobnahello\nexport var=value
. Jednym z niewielu innych poleceń, które zapewniają spójny wynik we wszystkich powłokach POSIX, jestenv
jednak trudniejsze do przeanalizowania, ponieważ brakuje w nimexport =
bitu.Odpowiedzi:
W awk jest dość łatwe.
Jednak uważaj niektóre implementacje awk dodać zmienne środowiskowe własnych (np GNU awk dodaje
AWKPATH
iAWKLIBPATH
doENVIRON
).Dane wyjściowe są niejednoznaczne, jeśli nazwa zmiennej środowiskowej zawiera nowy wiersz, co jest niezwykle nietypowe, ale technicznie możliwe. Rozwiązanie czystego sh byłoby trudne. Najlepiej zacząć od tego,
export -p
ale masowanie go w czystym sh jest trudne. Można użyć sed do masażu wyjścieexport -p
, a następnie użyćeval
, aby uzyskać powłokę, aby usunąć to, co cytowany. Bash i zsh drukują niestandardowe prefiksy.Zauważ, że w zależności od powłoki,
export -p
może, ale nie musi pokazywać zmiennych, których nazwa jest niepoprawna w powłoce, a jeśli nie, to może, ale nie musi, poprawnie podawać nazwy. Na przykład dash, mksh i zsh pomijają zmienne, których nazwa zawiera znak nowej linii, BusyBox dash i ksh93 drukują je na surowo, a bash drukuje je na surowo bez ich wartości. Jeśli musisz bronić się przed niezaufanymi danymi wejściowymi, nie polegaj na czystym rozwiązaniu POSIX i zdecydowanie nie wzywajeval
niczego pochodzącego z danych wyjściowychexport -p
.źródło
exit
jest to konieczne).FOO<newline>BAR
zrobisz, nie wiesz, czy jest toFOO<newline>BAR
zmienna środowiskowa (któraexport -p
nie wyświetla się w przypadku większości powłok, zobaczenv $'FOO\nBAR=test' awk 'BEGIN{for (v in ENVIRON) print v}'
) czy zarówno zmienna środowiskowaFOO
iBAR
.awk
s ustawia własne zmienne środowiskowe (AWKPATH
iAWKLIBPATH
w moim systemie)Lubię proste rzeczy; zadziała to dla systemów POSIX:
źródło
export AAA=$'multi\nBBB=line'
compgen -e
. To nie pomaga w moim przenośnym skrypcie (np. Gdy bash nie jest dostępny), ale jest interesujące.dash
w debianie, otrzymuję te same wyniki z powyższym poleceniem lub zmodyfikowałem,printenv | sed 's;*=.;;' | sort
aby uzyskać wartości. Wyeksportowałem zmiennąyo
i przypisałem jej twój pierwszy komentarz powyżej; wydrukowano zgodnie z oczekiwaniami, z wieloma liniami. nie jestem pewien, czego doświadczasz, ale nie powinno być obciętego wyjścia. uruchom polecenie w powłoce; cokolwiek wyjdzie, to jak powinno działać; nie oczekuj żadnego obcięcia. Następnie w kontekście TERMCAP / screen / iirc; powinno być takie samo. Jeśli dane wyjściowe nie są zgodne, to prawdopodobnie jest to problem z jednym z tych programów.