Mengekspor fungsi di shell

87

Tolong beritahu saya bagaimana cara mengekspor fungsi di shell induk (bash, sh atau ksh) sehingga fungsi tersebut akan tersedia untuk semua proses anak yang diluncurkan dari proses induk?

Sachin Chourasiya
sumber
1
unix.stackexchange.com/questions/22796/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Jawaban:

106

The export -ffitur khusus untuk Bash:

induk

#!/bin/bash
plus1 () { echo $(($1 + 1)); }
echo $(plus1 8)
export -f plus1
./child 14 21

anak

#!/bin/bash
echo $(plus1 $(($1 * $2)) )
Dennis Williamson
sumber
2
apakah fungsi yang diekspor hanya tersedia untuk panggilan anak? Bagaimana cara menerapkannya ke sesi bash saat ini? suka menulis .bashrc, tetapi hanya untuk contoh bash saat ini ...
vp_arth
3
@vp_arth: Jika Anda tidak memerlukan fungsi dalam panggilan anak, Anda tidak perlu mengekspornya. Ini tersedia di sesi saat ini dengan cara apa pun (perhatikan bahwa jika itu ditentukan dalam file, Anda harus mencari file daripada menjalankannya untuk membuatnya tersedia di sesi saat ini).
Dennis Williamson
3

Jika Anda menggunakan ksh atau zsh:

Anda dapat menggunakan variabel lingkungan FPATH, di mana Anda dapat menempatkan semua fungsi Anda.

Jika FPATHdiatur pada interpreter interaktif, dan perintah atau fungsi tidak ditemukan di lingkungan shell saat ini atau PATH, direktori yang terdaftar di sana mencari keberadaan file yang dinamai setelah perintah yang hilang. Jika ditemukan, itu bersumber di lingkungan shell saat ini, dan diharapkan dapat menentukan fungsinya.

Jadi, Anda dapat menempatkan semua fungsi Anda di satu lokasi FPATH, dan skrip anak juga akan dapat menemukannya.

Anda dapat menggunakan autoloadperintah dalam skrip shell untuk memuat fungsi yang Anda perlukan:

autoload fun_a fun_b

Dalam zsh, autoloaddiperlukan untuk FPATHbekerja. Dalam kshdan kerabat dekatnya, saya percaya itu hanya menyebabkan fungsi yang ditentukan FPATHuntuk menimpa perintah biasa di PATH Anda, seperti yang akan mereka lakukan jika didefinisikan secara langsung.

Beberapa detail FPATHdan autoload:

Venkataramesh Kommoju
sumber
1

Jika Anda membuat subkulit dengan, ( )mereka akan mewarisi cuplikan dari semua definisi, parameter, dan variabel shell.

Jika Anda menjalankannya seperti program maka Anda dapat memasukkan definisi .bashrc.

Jika Anda mencoba untuk memalsukan skrip yang ada untuk menjalankan pembungkus atau substitusi untuk perintah PATH, maka .bashrcakan berfungsi tergantung pada detail eksekusi. Jika tidak, Anda dapat menjalankan skrip pembungkus yang hanya melakukan .atau sourcedari file include yang mendefinisikan fungsi dan kemudian melakukan hal yang sama dengan skrip shell dengan perintah yang akan diganti.

Skrip pembungkus mungkin terlihat seperti ini:

script=$1
shift
. include.sh
. $script "$@"

Idenya adalah bahwa parameter pertama adalah nama skrip asli dan parameter yang tersisa adalah args, kemudian skrip di atas dijalankan.

DigitalRoss
sumber
2
Bisakah Anda menjelaskan ini dengan beberapa contoh pengkodean. Saya tidak ingin menempatkan fungsi saya di .bashrc
Sachin Chourasiya
1
declare -x -f NAME

Info lebih lanjut

-f membatasi aksi atau tampilan ke nama fungsi dan definisi
-x untuk mengekspor NAMA
Steven Penny
sumber
6
Harap dicatat bahwa ini khusus untukbash . ( kshpasangan untuk declare,, typesetmemiliki -xopsi, tetapi hanya berlaku untuk variabel , bukan fungsi; ditto untuk zsh).
mklement0
0

Fungsi tidak dapat diekspor secara alami. Bagaimanapun Anda dapat mengekspor string, jadi saya punya sedikit trik di sini:

func="$(typeset -f funcname)"
export func

Untuk mengimpor fungsi, tentukan ulang dari string yang diekspor:

# in subshell
eval "$func"
iBug
sumber