set
akan menampilkan variabel, sayangnya itu juga akan menampilkan fungsi yang didefinisikan juga.
Untungnya mode POSIX hanya menampilkan variabel:
( set -o posix ; set ) | less
Mengalihkan ke less
, atau mengalihkan ke tempat Anda menginginkan opsi.
Jadi untuk mendapatkan variabel yang dideklarasikan hanya dalam skrip:
( 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
(Atau setidaknya sesuatu berdasarkan itu :-))
-o posix
sekarang diff hanya akan berisi variabel.VARS="`set -o posix ; set`"; source script; SCRIPT_VARS="`grep -vFe "$VARS" <<<"$(set -o posix ; set)" | grep -v ^VARS=`"; unset VARS;
. Ini juga akan menampilkan vars dalam format yang siap disimpan. Daftar akan menyertakan variabel yang diubah skrip (tergantung apakah ini diinginkan)source
, Anda harus dapat melakukannya dengan keluarandeclare -p
.before=$(set -o posix; set); dosomestuff; diff <(echo "$before") <(set -o posix; set)
Ini mencantumkan semua variabel termasuk yang lokal. Saya mempelajarinya dari Dapatkan daftar variabel yang namanya cocok dengan pola tertentu , dan menggunakannya dalam skrip saya .
sumber
compgen -v
daftar juga variabel global yang tidak disetel secara lokal. Tidak yakin apakah itu bug lama atau perilaku yang diinginkan.Ini harus mencetak semua nama variabel shell. Anda bisa mendapatkan daftar sebelum dan sesudah mencari file Anda seperti "set" ke diff variabel mana yang baru (seperti yang dijelaskan di jawaban lain). Namun perlu diingat bahwa pemfilteran dengan diff dapat menyaring beberapa variabel yang Anda butuhkan tetapi ada sebelum mencari file Anda.
Dalam kasus Anda, jika Anda tahu nama variabel Anda diawali dengan "VARIABEL", Anda dapat mengambil skrip Anda dan melakukan:
UPDATE: Untuk solusi BASH murni (tidak ada perintah eksternal yang digunakan):
sumber
eval "printf '%q\n' $(printf ' "${!%s@}"' _ {a..z} {A..Z})"
Berdasarkan beberapa jawaban di atas, ini berhasil untuk saya:
file sumber :
sumber
Jika Anda dapat melakukan pasca-proses, (seperti yang telah disebutkan) Anda dapat melakukan
set
panggilan di awal dan akhir skrip Anda (masing-masing ke file yang berbeda) dan melakukan perbedaan pada kedua file. Sadarilah bahwa ini masih akan mengandung sedikit kebisingan.Anda juga dapat melakukan ini secara terprogram. Untuk membatasi keluaran hanya ke lingkup Anda saat ini, Anda harus menerapkan pembungkus untuk pembuatan variabel. Sebagai contoh
Hasil yang mana
sumber
Berikut ini sesuatu yang mirip dengan jawaban @GinkgoFr, tetapi tanpa masalah yang diidentifikasi oleh @Tino atau @DejayClayton, dan lebih kuat daripada
set -o posix
bit pintar @ DouglasLeeder :Perbedaannya adalah bahwa solusi ini BERHENTI setelah laporan non-variabel pertama, misalnya fungsi pertama yang dilaporkan oleh
set
BTW: Masalah "Tino" sudah terpecahkan. Meskipun POSIX dimatikan dan fungsi dilaporkan oleh
set
,sed ...
porsi solusi hanya memungkinkan laporan variabel melalui (misalnyaVAR=VALUE
baris). Secara khusus,A2
tidak tidak spuriously membuatnya menjadi output.DAN: Masalah "DejayClayton" telah terpecahkan (baris baru yang disematkan dalam nilai variabel tidak mengganggu keluaran - masing-masing
VAR=VALUE
mendapatkan satu baris keluaran):CATATAN: Solusi yang disediakan oleh @DouglasLeeder mengalami masalah "DejayClayton" (nilai dengan baris baru yang disematkan). Di bawah ini,
A1
salah danA2
seharusnya tidak ditampilkan sama sekali.AKHIRNYA: Menurut saya versi
bash
masalahnya, tapi mungkin saja. Saya melakukan pengujian / pengembangan saya yang satu ini:POST-SCRIPT: Mengingat beberapa tanggapan lain untuk OP, saya <100% yakin bahwa
set
selalu mengubah baris baru dalam nilai\n
, yang mana solusi ini bergantung untuk menghindari masalah "DejayClayton". Mungkin itu perilaku modern? Atau variasi waktu kompilasi? Atau pengaturanset -o
ataushopt
opsi? Jika Anda mengetahui variasi seperti itu, silakan tambahkan komentar ...sumber
Coba gunakan skrip (sebut saja "ls_vars"):
chmod + x itu, dan:
sumber
Dari perspektif keamanan, baik @ akostadinov ini jawaban atau @ JuvenXu ini jawabannya adalah lebih baik untuk mengandalkan output terstruktur dari
set
perintah, karena lubang keamanan potensial berikut:Fungsi di atas
doLogic
digunakanset
untuk memeriksa keberadaan variabelPS1
untuk menentukan apakah skrip itu interaktif atau tidak (tidak masalah apakah ini cara terbaik untuk mencapai tujuan itu; ini hanya sebuah contoh.)Namun, keluaran dari
set
tidak terstruktur, yang berarti bahwa variabel apa pun yang berisi baris baru dapat mencemari hasil secara total.Ini, tentu saja, merupakan risiko keamanan potensial. Sebagai gantinya, gunakan dukungan Bash untuk perluasan nama variabel tidak langsung, atau
compgen -v
.sumber
Coba ini:
set | egrep "^\w+="
(dengan atau tanpa| less
pemipaan)Solusi yang diusulkan pertama
( set -o posix ; set ) | less
,, berfungsi tetapi memiliki kekurangan: ia mentransmisikan kode kontrol ke terminal, sehingga tidak ditampilkan dengan benar. Jadi misalnya, jika ada (kemungkinan) suatuIFS=$' \t\n'
variabel, kita dapat melihat:…sebagai gantinya.
egrep
Solusi saya menampilkan ini (dan akhirnya yang serupa lainnya) dengan benar.sumber
bash -c $'a() { echo "\nA=B"; }; unset A; set | egrep "^\w+="' | grep ^A
tampilan yang salahA=B"
-> Gagal!Saya mungkin telah mencuri jawabannya beberapa waktu yang lalu ... toh sedikit berbeda sebagai fungsi:
sumber
The
printenv
perintah:printenv
mencetak semuaenvironment variables
nilai mereka.Semoga berhasil...
sumber
Cara sederhana untuk melakukannya adalah dengan menggunakan mode ketat bash dengan menyetel variabel lingkungan sistem sebelum menjalankan skrip Anda dan menggunakan diff untuk hanya mengurutkan skrip Anda:
Sekarang Anda dapat mengambil variabel dari skrip Anda di /tmp/script_vars.log. Atau setidaknya sesuatu berdasarkan itu!
sumber
Sedikit terlambat ke pesta, tapi inilah saran lainnya:
Baris perintah pipa diff + sed mengeluarkan semua variabel yang ditentukan skrip dalam format yang diinginkan (seperti yang ditentukan dalam posting OP):
sumber