Jadi saya mulai menggunakan zsh
. Saya suka semuanya. Tampaknya sangat keren dan apik, dan fakta bahwa direktori kerja saat ini dan baris perintah aktual pada baris yang berbeda adalah baik, tetapi pada saat yang sama, saya memperhatikan bahwa itu zsh
bisa sedikit lebih lambat daripada bash
, terutama ketika mencetak teks ke layar.
Hal yang paling saya sukai adalah fakta bahwa zsh
'kompatibel dengan' semua fungsi yang saya definisikan di .bashrc
.
Namun satu keluhan. Semua fungsinya bekerja dengan sempurna, tapi saya tidak tahu cara kerja sistem ekspor.
Saya memiliki beberapa .bashrc
fungsi yang diekspor sehingga saya dapat menggunakannya di tempat lain, seperti dalam skrip dan program eksternal export -f
.
Di zsh, ekspor sepertinya tidak dibicarakan. Apakah ini autoloading? Apakah kedua hal itu sama? Saya mengalami kesulitan serius mencari tahu itu.
sumber
Jawaban:
Variabel lingkungan yang mengandung fungsi adalah bash hack. Zsh tidak memiliki yang serupa. Anda dapat melakukan sesuatu yang serupa dengan beberapa baris kode. Variabel lingkungan mengandung string; versi bash yang lebih lama, sebelum Shellshock ditemukan, menyimpan kode fungsi dalam variabel yang namanya adalah fungsi dan yang nilainya
() {
diikuti oleh kode fungsi diikuti oleh}
. Anda dapat menggunakan kode berikut untuk mengimpor variabel dengan penyandian ini, dan mencoba menjalankannya dengan pengaturan mirip-bash. Perhatikan bahwa zsh tidak dapat mengemulasi semua fitur bash, yang dapat Anda lakukan adalah sedikit lebih dekat (mis. Untuk$foo
memisahkan nilai dan memperluas wildcard, dan membuat array berbasis 0).(Seperti Stéphane Chazelas , penemu asli Shellshock, mencatat, versi sebelumnya dari jawaban ini dapat mengeksekusi kode arbitrer pada titik ini jika definisi fungsi salah. Versi ini tidak, tetapi tentu saja begitu Anda menjalankan perintah, bisa jadi fungsi yang diimpor dari lingkungan.)
Versi Post-Shellshock dari fungsi bash encode di lingkungan menggunakan nama variabel yang tidak valid (misalnya
BASH_FUNC_myfunc%%
). Ini membuat mereka lebih sulit untuk menguraikan dengan andal karena zsh tidak menyediakan antarmuka untuk mengekstrak nama variabel seperti itu dari lingkungan.Saya tidak merekomendasikan melakukan ini. Mengandalkan fungsi yang diekspor dalam skrip adalah ide yang buruk: itu menciptakan ketergantungan yang tidak terlihat dalam skrip Anda. Jika Anda pernah menjalankan skrip Anda di lingkungan yang tidak memiliki fungsi Anda (di komputer lain, dalam tugas cron, setelah mengubah file inisialisasi shell Anda, ...), skrip Anda tidak akan berfungsi lagi. Alih-alih, simpan semua fungsi Anda dalam satu atau beberapa file terpisah (seperti
~/lib/shell/foo.sh
) dan mulai skrip Anda dengan mengimpor fungsi yang digunakannya (. ~/lib/shell/foo.sh
). Dengan cara ini, jika Anda memodifikasifoo.sh
, Anda dapat dengan mudah mencari skrip mana yang bergantung padanya. Jika Anda menyalin skrip, Anda dapat dengan mudah menemukan file tambahan yang dibutuhkan.Zsh (dan ksh sebelum itu) membuat ini lebih nyaman dengan menyediakan cara untuk memuat fungsi secara otomatis dalam skrip di mana mereka digunakan. Batasannya adalah Anda hanya dapat menempatkan satu fungsi per file. Deklarasikan fungsi sebagai autoloaded, dan letakkan definisi fungsi dalam file yang namanya adalah nama fungsi. Masukkan file ini ke direktori yang terdaftar
$fpath
(yang dapat Anda konfigurasikan melaluiFPATH
variabel lingkungan). Dalam skrip Anda, deklarasikan fungsi-fungsi yang diisi-otomatis denganautoload -U foo
.Selanjutnya zsh dapat mengkompilasi skrip, untuk menghemat waktu parsing. Panggil
zcompile
untuk menyusun skrip. Ini menciptakan file dengan.zwc
ekstensi. Jika file ini ada makaautoload
akan memuat file yang dikompilasi alih-alih kode sumber. Anda dapat menggunakanzrecompile
fungsi untuk (mengkompilasi) semua definisi fungsi dalam direktori.sumber
bash
(tidak memverifikasi bahwa konten variabel hanya definisi fungsi dan memproses nama variabel sepertiHTTP_HOST
atauLC_X
). Jawaban yang bagus sebaliknya.zsh -c 'functions[f]=$VAR'
yang diurai bahkan jikaf
fungsi tidak pernah disebut). Solusinya adalah dengan mempertimbangkan hanya variabel yang namanya mengikuti templat yang dicadangkan seperti itu$BASH_FUNC_x%%
, tetapi seperti yang Anda katakan,zsh
tidak memiliki API untuk mendaftar atau mengambilnya. Anda harus meneleponperl
misalnya.Jika Anda menempatkan deklarasi fungsi Anda di .zshenv , fungsi Anda akan dapat digunakan dari skrip tanpa upaya apa pun.
sumber
.zshenv
dan memperlambat setiap permintaan zsh dengan mem-parsing banyak kode yang tidak pernah digunakan. Lebih jauh itu tidak sama dengan mengekspor suatu fungsi, seperti halnya variabel yang diekspor, fungsi yang diekspor hanya tersedia untuk proses anak. Sedangkan barang yang Anda masukkan.zshenv
tersedia untuk setiap zsh..zshenv
, maka semua skrip Anda akan sepenuhnya non-portabel. Biasanya skrip bisa saling bergantung, yang baik-baik saja, Anda bagikan bersama. Tetapi jika mereka bergantung pada memiliki fungsi khusus.zshenv
, tidak ada yang mau menggunakannya, atau mereka harus dipanggil dengan khususZDOTDIR
, mencegah Anda sendiri.zshenv
dieksekusi. Itu akan menyebalkan.