Perintah bash builtin set
, jika dijalankan tanpa argumen, akan mencetak semua variabel shell dan environment, tetapi juga semua fungsi yang didefinisikan. Ini membuat output tidak dapat digunakan oleh manusia dan sulit untuk dilakukan grep
.
Bagaimana saya bisa membuat perintah bash builtin set
hanya mencetak variabel dan bukan fungsinya?
Apakah ada perintah lain yang hanya mencetak variabel shell, tanpa fungsi?
Catatan: bash membedakan antara variabel shell dan variabel lingkungan. lihat di sini Perbedaan antara variabel lingkungan dan variabel lingkungan yang diekspor di bash
sumber
_
, yang mudah untuk dihilangkan:(set -o posix ; set | grep -v ^_)
set -o posix; set | sed -e '/^_/,$d'; set +o posix;
(set -o posix; set)
. Tanpa tanda kurung perilaku shell Bash saat ini akan diubah agar sesuai dengan standar Posix. (Entah apa artinya tapi terlihat penting.) Dengan tanda kurung, Bash tetap tidak berubah.POSIXLY_CORRECT=y
dan menambahkanposix
ke$SHELLOPTS
Berikut ini beberapa solusinya:
kerusakan:
declare
mencetak setiap variabel yang ditentukan (diekspor atau tidak) dan berfungsi.declare -f
hanya mencetak fungsi.comm -3
akan menghapus semua baris yang umum untuk keduanya. Akibatnya ini akan menghapus fungsi, hanya menyisakan variabel.Untuk hanya mencetak variabel yang tidak diekspor:
Solusi lain:
Ini hanya akan mencetak variabel, tetapi dengan beberapa atribut jelek.
Anda dapat memotong atribut menggunakan ... potong:
Satu kelemahannya adalah bahwa nilai IFS ditafsirkan alih-alih ditampilkan.
membandingkan:
Ini membuatnya sangat sulit untuk menggunakan output itu untuk diproses lebih lanjut, karena itu satu-satunya
"
dalam satu baris. Mungkin beberapa IFS-fu dapat dilakukan untuk mencegah hal ini.Solusi lain, menggunakan
compgen
:Bash builtin
compgen
dimaksudkan untuk digunakan dalam skrip penyelesaian. Untuk tujuan ini,compgen -v
daftarkan semua variabel yang ditentukan. The downside: itu hanya mencantumkan nama variabel, bukan nilai.Berikut ini adalah retasan untuk juga mencantumkan nilai.
Keuntungan: itu adalah solusi bash murni. Kerugiannya: beberapa nilai kacau karena interpretasi yang mendalam
printf
. Subkulit dari pipa dan / atau loop menambahkan beberapa variabel tambahan.sumber
declare ...| cut
pipa Anda pecah jika tidak ada atribut untuk variabel? Saya menduga itu--
digunakan dalam kasus itu, tapi saya masih gelisah.sed
mungkin lebih aman, yaitudeclare -p | sed 's/^.* \([^ ]\+\)$/\1/'
compgen
:)The
typeset
builtin anehnya memiliki pilihan untuk menampilkan fungsi saja (-f
) tapi tidak untuk menunjukkan parameter saja. Untungnya,typeset
(atauset
) menampilkan semua parameter sebelum semua fungsi, fungsi dan nama parameter tidak dapat berisi baris baru atau tanda sama dengan, dan baris baru dalam nilai parameter dikutip (mereka muncul sebagai\n
). Jadi Anda bisa berhenti di baris pertama yang tidak mengandung tanda sama dengan:Ini hanya mencetak nama parameter; jika Anda menginginkan nilainya, ubah
print $1
keprint $0
.Perhatikan bahwa ini mencetak semua nama parameter (parameter dan variabel digunakan secara sinonim di sini), bukan hanya variabel lingkungan ("variabel lingkungan" identik dengan "parameter yang diekspor").
Perhatikan juga bahwa ini mengasumsikan tidak ada variabel lingkungan dengan nama yang tidak cocok dengan batasan bash pada nama parameter. Variabel seperti itu tidak dapat dibuat di dalam bash tetapi bisa diwarisi dari lingkungan saat bash dimulai:
sumber
set | sed '/=/!Q'
Saya tidak yakin bagaimana orang dapat membuat
set
variabel hanya mencetak. Namun dengan melihat output dariset
, saya bisa datang dengan yang berikut ini yang tampaknya mengambil hanya variabel:Pada dasarnya, saya mencari garis yang dimulai dengan huruf, angka, atau tanda baca diikuti oleh "=". Dari output yang saya lihat, ini mengambil semua variabel; Namun, saya ragu bahwa ini sangat portabel.
Jika, seperti judul Anda menyarankan, Anda ingin mengurangi dari daftar ini variabel yang diekspor dan dengan demikian mendapatkan daftar variabel yang tidak diekspor, maka Anda bisa melakukan sesuatu seperti ini
Untuk sedikit menguraikan hal ini, inilah fungsinya:
set | grep "^\([[:alnum:]]\|[[:punct:]]\)\+=" | sort > ./setvars
: Mudah-mudahan ini mendapatkan semua variabel (seperti yang dibahas sebelumnya), mengurutkannya, dan menempelkan hasilnya dalam file.&& env | sort
: Setelah perintah sebelumnya selesai, kita akan memanggilenv
dan mengurutkan hasilnya.| comm -23 ./setvars -
: Akhirnya, kami menyalurkan output yang diurutkanenv
menjadicomm
dan menggunakan-23
opsi untuk mencetak garis yang unik untuk argumen pertama, dalam hal ini garis yang unik untuk output kami dari set.Ketika Anda selesai, Anda mungkin ingin membersihkan file temp yang dibuat dengan perintah
rm ./setvars
sumber
f () {|cat <<EOF|foo=bar|EOF|}
mana|
merupakan pemisah baris).Cukup gunakan perintah
env
. Itu tidak mencetak fungsi.sumber
Coba perintah printenv:
sumber
Dalam bash, ini hanya akan mencetak nama variabel:
Atau, jika nilai juga diperlukan, gunakan:
sumber
berbeda dengan shell yang bersih untuk memastikan vars dari skrip rc bisa ditinggalkan
versi dengan
comm
akan terlalu berbelit-belitsumber
Jawaban yang diterima bagus. Saya menawarkan alternatif yang tidak melibatkan pengaturan mode POSIX:
Inilah teknik yang telah saya gunakan untuk menyimpan status fungsi ke file sehingga saya bisa melanjutkannya nanti. Yang pertama menghasilkan dump negara dan yang kedua hanya menghasilkan daftar nama-nama variabel.
Keduanya bekerja dengan membuang baris hingga menemukan satu tanpa char '=', yang terjadi ketika fungsi pertama terdaftar. Yang terakhir memotong tugas.
sumber