Bagaimana Anda menentukan apakah variabel shell diekspor atau tidak?

13

Dengan keluarga shell Bourne, variabel shell semua memiliki nama-nama huruf besar; yang berarti Anda tidak dapat mengetahui apakah variabel tertentu adalah variabel lingkungan atau tidak hanya dengan melihat namanya. Bagaimana Anda menentukan variabel shell Bourne mana yang lokal (hanya didefinisikan dalam shell saat ini)?

Shoulderpadz
sumber
4
Bourne shell atau Bourne-again shell? Bisakah Anda menunjuk ke referensi untuk hal huruf besar?
Jeff Schaller
Di shell Bourne-again karena semua variabel adalah huruf besar, bagaimana Anda bisa menentukan variabel bash mana yang lokal?
Shoulderpadz
7
@Shoulderpadz tidak ada yang mencegah Anda membuat variabel huruf kecil.
muru
1
Dengan lokal yang Anda maksud variabel yang belum diekspor?
Eliah Kagan
4
Perbedaan yang Anda tanyakan adalah variabel shell vs variabel lingkungan, bukan global vs lokal. Perhatikan bahwa ada variabel shell yang bukan variabel lingkungan (yaitu, apa yang Anda sebut "lokal"), dan ada variabel lingkungan yang bukan variabel shell (lingkungan dapat berisi nama yang bukan pengidentifikasi shell yang valid, dan dengan demikian tidak dapat berupa variabel).
chepner

Jawaban:

17

Jika Anda ingin melihat apakah suatu variabel diekspor atau tidak, gunakan declare:

$ foo=a bar=b
$ export foo
$ declare -p foo bar
declare -x foo="a"
declare -- bar="b"
muru
sumber
26

Cara yang paling portabel adalah export -p.

export -pdaftar variabel yang diekspor. Ini biasanya seperti declare -x, jika shell Anda memiliki declare.

Kerang Bourne-style yang sedang digunakan harus mendukung export -p, seperti yang disyaratkan oleh POSIX :

Ketika -p ditentukan, ekspor harus menulis ke output standar nama dan nilai dari semua variabel yang diekspor, dalam format berikut:

"export %s=%s\n", <name>, <value>

jika nama diatur, dan:

"export %s\n", <name>

jika nama tidak disetel.

Standar selanjutnya menjelaskan bahwa nilai variabel ditampilkan sedemikian rupa yang biasanya memungkinkannya untuk digunakan nanti di sisi kanan =dalam penugasan. Ini untuk mengatakan bahwa itu dapat dikutip. Kerang yang berbeda dapat menampilkannya secara berbeda tetapi dengan efek yang sama. export -pbekerja bahkan di shell yang tidak memiliki declarebuiltin, seperti Dash .

$ dash -c 'export -p | grep HOME='  # busybox sh and other ash give the same output.
export HOME='/home/ek'
$ posh -c 'export -p | grep HOME='  # ksh93, mksh, lksh, and others give the same output.
export HOME=/home/ek

Saya telah memipipkan output ke grepuntuk kekompakan tetapi jika Anda tidak memfilternya maka Anda mendapatkan daftar lengkap dari variabel yang diekspor. Dari pertanyaan Anda, sepertinya itulah yang menurut Anda paling berguna.

Beberapa shell, seperti Bash, menggunakan format non-standar kecuali diperintahkan secara eksplisit untuk berperilaku sesuai cara POSIX. Di Bash export -pmemberikan output yang sama declare -xdengan default.

$ bash -c 'export -p | grep HOME='
declare -x HOME="/home/ek"
$ bash -c 'POSIXLY_CORRECT= export -p | grep HOME='
export HOME="/home/ek"
$ bash -c 'set -o posix; export -p | grep HOME='
export HOME="/home/ek"
$ bash --posix -c 'export -p | grep HOME='
export HOME="/home/ek"
$ ln -s /bin/bash sh
$ ./sh -c 'export -p | grep HOME='  # Invoking bash as sh also puts it in POSIX mode.
export HOME="/home/ek"

Zsh menunjukkan format yang tidak standar bahkan ketika kompatibilitas POSIX diaktifkan:

$ zsh -c 'export -p | grep HOME='
typeset -x HOME=/home/ek
$ zsh -c 'emulate -R sh; export -p | grep HOME='
typeset -x HOME=/home/ek
$ ln -s /bin/zsh sh
$ ./sh -c 'export -p | grep HOME='
typeset -x HOME=/home/ek

Dalam kasus apa pun, Anda dapat mengekstraksi representasi portabel (yang dapat dikutip) dengan mencari kata yang diikuti oleh =. Ini tidak bergantung pada kata-kata sebelumnya di telepon, asalkan mereka tidak segera mendahului =, yang seharusnya tidak mereka lakukan. Sebagai contoh:

% export -p | grep -oE '\w+=.*'
HOME=/home/ek
LANG=en_US.UTF-8
LESSCLOSE='/usr/bin/lesspipe %s %s'
....

Perhatikan bahwa tidak semua entri memiliki =. Ini karena variabel dapat tidak disetel tetapi diekspor. Entri-entri itu disaring oleh grepperintah di atas, yang mungkin atau mungkin tidak seperti yang Anda inginkan.

Sebagian besar waktu, Anda hanya ingin memeriksa output dan sehingga Anda tidak akan peduli jika entri didahului oleh export, declare -x, typeset -x, atau sesuatu yang lain. Maka jalankan saja export -p.

Saya menguji perintah-perintah itu di Ubuntu 16.04 LTS dengan versi resmi setiap paket shell.

Eliah Kagan
sumber
0

Variabel yang TIDAK diekspor dapat dilihat dari output declareperintah di bash.

Variabel yang sedang diekspor dapat dilihat dari output declare -xatau exportperintah di bash.

S471
sumber