Dengan cara yang kompatibel dengan posix yang bekerja dengan banyak implementasi, bagaimana saya bisa mencetak daftar variabel lingkungan yang didefinisikan saat ini tanpa nilainya?
Pada beberapa implementasi (mksh, freebsd / bin / sh), hanya menggunakan export
dengan sendirinya akan sesuai dengan tagihan:
$ export
FOO2
FOO
Tetapi untuk beberapa implementasi lainnya (bash, zsh, dash), export
juga menunjukkan nilainya. Dengan bash, misalnya:
$ 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$
Opsi lain suka env
atau printenv
tidak memiliki opsi untuk mencetak hanya nama variabel tanpa nilai, setidaknya tidak pada platform linux dan freebsd yang saya coba.
Perpipaan ke awk / sed / etc. atau memotong daftar dengan teknik ekspansi parameter (misalnya, ${foo%%=*}
) dapat diterima, tetapi harus bekerja dengan nilai-nilai yang dapat menjangkau garis dan memiliki =
dan spasi kosong dalam nilai (lihat contoh di atas).
Jawaban spesifik untuk implementasi shell tertentu menarik, tetapi saya terutama mencari sesuatu yang kompatibel di seluruh implementasi.
export -p
yang ditentukan oleh POSIX untuk menghasilkan output yang juga cocok untuk input di shell.export -p
ini?export -p
karena itu akan memberi Anda output yang konsisten di semua shell POSIX, yang Anda katakan Anda inginkan.export -p
tidak sesuai dengan persyaratan pertama - hanya mencetak nama variabel tanpa nilai.export -p
. Saya tidak akan menulis parsing itu, karena dalam kasus umum, itu juga harus melakukan parsing kutipan yang tepat, jika Anda memiliki variabel yang nilainya sepertihello\nexport var=value
. Salah satu dari beberapa perintah lain yang akan memberi Anda output yang konsisten di semua shell POSIX adalahenv
, tetapi output itu lebih sulit untuk diurai karena tidak memilikiexport =
bit.Jawaban:
Sangat mudah dalam awk.
Namun waspadalah beberapa implementasi awk menambahkan variabel lingkungannya sendiri (mis. GNU awk add
AWKPATH
andAWKLIBPATH
toENVIRON
).Outputnya ambigu jika nama variabel lingkungan berisi baris baru, yang sangat tidak biasa tetapi secara teknis memungkinkan. Solusi murni akan sulit. Taruhan terbaik Anda adalah memulainya
export -p
tetapi memijatnya dengan benar tidak sulit. Anda dapat menggunakan sed untuk memijat outputexport -p
, lalu gunakaneval
untuk mendapatkan shell untuk menghapus apa yang dikutip. Bash dan zsh mencetak awalan non-standar.Perhatikan bahwa tergantung pada shell,
export -p
mungkin atau mungkin tidak menampilkan variabel yang namanya tidak valid dalam shell, dan jika tidak, maka mungkin atau mungkin tidak mengutip nama-nama dengan benar. Misalnya, tanda hubung, mksh dan zsh menghilangkan variabel yang namanya menyertakan baris baru, BusyBox dash dan ksh93 mencetaknya mentah, dan bash mencetaknya mentah tanpa nilainya. Jika Anda perlu mempertahankan terhadap input yang tidak tepercaya, jangan mengandalkan solusi POSIX murni, dan pasti tidak memintaeval
apa pun yang berasal dari outputexport -p
.sumber
exit
tidak perlu).FOO<newline>BAR
, Anda tidak tahu apakah ituFOO<newline>BAR
variabel lingkungan (yangexport -p
tidak akan ditampilkan pada sebagian besar shell, lihatenv $'FOO\nBAR=test' awk 'BEGIN{for (v in ENVIRON) print v}'
) atau keduanya aFOO
danBAR
variabel lingkungan.awk
menetapkan variabel lingkungannya sendiri (AWKPATH
danAWKLIBPATH
pada sistem saya)Saya suka hal-hal sederhana; ini akan bekerja untuk sistem POSIX:
sumber
export AAA=$'multi\nBBB=line'
compgen -e
. Itu tidak membantu untuk skrip portabel saya (misalnya, ketika bash tidak tersedia), tetapi menarik.dash
di debian, saya mendapatkan hasil yang sama dengan perintah di atas atau, dimodifikasiprintenv | sed 's;*=.;;' | sort
untuk mendapatkan nilai. Saya mengekspor variabelyo
dan memberikannya komentar pertama Anda di atas; itu dicetak seperti yang diharapkan, dengan beberapa baris. tidak yakin apa yang Anda alami tetapi seharusnya tidak ada output yang terpotong. jalankan perintah di shell; apa pun yang dihasilkan di situ adalah cara kerjanya; berharap tidak memotong. Kemudian, dalam konteks TERMCAP / layar / iirc; harus sama. Jika output tidak cocok maka kemungkinan ada masalah dengan salah satu program tersebut.