source some_file
some_file:
doit ()
{
echo doit $1
}
export TEST=true
Jika saya sumber some_file fungsi "doit" dan variabel TEST tersedia di baris perintah. Tetapi menjalankan skrip ini:
script.sh:
#/bin/sh
echo $TEST
doit test2
Akan mengembalikan nilai TEST, tetapi akan menghasilkan kesalahan tentang fungsi tidak dikenal "doit".
Bisakah saya "mengekspor" fungsinya juga, atau apakah saya harus sumber some_file di script.sh untuk menggunakan fungsi di sana?
#!/bin/sh
ke#!/bin/bash
dan setelahdoit() {...}
sajaexport -f doit
#!/bin/sh
juga, tetapi ini adalah praktik yang baik untuk digunakan#!/bin/bash
sehingga Anda menghindari masalah saat shell default tidak bash.Jawaban:
Di Bash Anda dapat mengekspor definisi fungsi ke sub-shell dengan
Misalnya, Anda dapat mencoba contoh sederhana ini:
./script1
:./script2
:Maka jika Anda menelepon,
./script1
Anda akan melihat hasilnya Hello! .sumber
"Mengekspor" suatu fungsi menggunakan
export -f
menciptakan variabel lingkungan dengan badan fungsi. Pertimbangkan contoh ini:Ini berarti bahwa hanya shell (hanya Bash?) Yang dapat menerima fungsinya. Anda juga bisa mengatur sendiri fungsinya karena Bash hanya menganggap envvars yang dimulai dengan
() {
fungsi:Jika Anda perlu "mengekspor" variabel ini melalui SSH, maka Anda benar-benar membutuhkan fungsi sebagai string. Ini dapat dilakukan dengan opsi cetak (
-p
) untuk fungsi (-f
)declare
bawaan:Ini sangat berguna jika Anda memiliki kode yang lebih kompleks yang perlu dijalankan melalui SSH. Pertimbangkan skrip fiktif berikut:
sumber
fn2='() { echo Hi;}' sh -c fn2
tidak bekerja untuk saya. Di lengkungan linux dengansh
menjadi bash v5.0.7 saya dapatkansh: fn2: command not found
. Di Ubuntu dengansh
sedang dash v0.2.3 saya dapatkansh: 1: fn2: not found
.sh
Shell mana yang Anda gunakan?f(){ echo a;}; export -f f; echo "$f"; sh -c 'printenv f; echo "$f"'
tidak mencetak apa pun untuk saya, jadi jelasf
tidak diekspor sebagai string biasa. Saya menguji dengan kedua kombinasi yang disebutkan di atas.sh
mengeksekusi string itu sebagai fungsi? Dalam contoh Andafn2='() { echo Hi;}' sh -c fn2
, perintah yangfn2
diberikansh
adalah string"fn2"
.sh
harus mencari perintah seperti itu di PATH-nya tetapi tidak harus melihat apakah ada variabel$fn2
, perluas variabel itu, dan jalankan nilainya sebagai fungsi - terdengar seperti masalah keamanan utama bagi saya. sunting: Saya pikir itu saja! Apakah perilaku Anda yang ditampilkan adalah bug keamanan yang dikenal sebagai ShellShock / Bashdoor ?fn(){ echo foo; }; export -f fn; env | grep foo
keluaranBASH_FUNC_fn%%=() { echo foo
Membangun jawaban @ Lekensteyn ...
Jika Anda menggunakannya
declare -pf
akan menampilkan semua fungsi yang didefinisikan sebelumnya di shell saat ini ke STDOUT.Pada titik itu Anda dapat mengarahkan kembali STDOUT ke mana pun Anda inginkan dan pada hakekatnya mengatur fungsi-fungsi yang telah ditentukan sebelumnya di mana pun Anda inginkan.
Jawaban berikut akan memasukkan mereka ke dalam variabel. Kemudian kita menggemakan variabel itu ditambah dengan pemanggilan fungsi yang ingin kita jalankan ke shell baru yang muncul sebagai pengguna baru. Kami melakukan ini dengan menggunakan
sudo
dengan saklar-u
(alias.user
) Dan hanya menjalankan Bash (yang akan menerima STDOUT yang disalurkan sebagai input untuk menjalankan).Seperti yang kita ketahui bahwa kita akan beralih dari shell Bash ke shell Bash kita tahu bahwa Bash akan menginterpretasikan fungsi-fungsi shell yang didefinisikan sebelumnya dengan benar. Sintaksnya akan baik-baik saja selama kita bergerak di antara satu shell Bash dari versi yang sama ke shell Bash baru dari versi yang sama.
YMMV jika Anda bergerak di antara shell yang berbeda atau antara sistem yang mungkin memiliki versi Bash yang berbeda.
sumber
Anda tidak dapat mengekspor fungsi, tidak dengan cara yang Anda gambarkan. Shell hanya akan memuat
~/.bashrc
file pada awal shell interaktif (cari "Doa" di halaman manual bash ).Yang bisa Anda lakukan adalah membuat "perpustakaan" yang dimuat ketika Anda memulai program:
Dan tempatkan fungsi dan pengaturan non-interaktif Anda di sana.
sumber
BASH_ENV
variabel lingkungan yangsome_file
sudah Anda miliki, dan itu akan dipanggil. Akan cukup mudah untuk mengetahuinya:echo echo foobar > /tmp/foobar; BASH_ENV=/tmp/foobar $SHELL -c :
eval "$(declare -F | sed -e 's/-f /-fx /')"
akan mengekspor semua fungsi.Saya sering melakukan ini sebelum memulai shell interaktif dalam skrip untuk memungkinkan saya melakukan debug dan bekerja dalam konteks skrip saat menggunakan fungsi dan variabelnya.
Contoh:
sumber
Fungsi tidak diekspor ke subproses. Inilah sebabnya mengapa ada file bernama .kshrc atau .bashrc: Untuk mendefinisikan fungsi yang harus tersedia dalam subkulit juga.
Jika menjalankan skrip, skrip. * Shrc biasanya tidak bersumber. Anda harus kode itu secara eksplisit, seperti di
. ~/.kshrc
.sumber
rm=rm -i
)Yah, saya baru mengenal Linux, tetapi Anda dapat mencoba ini. Dalam beberapa file, sebut saja, 'tmp / general' Anda membangun fungsi Anda:
Dalam skrip shell Anda tambahkan:
dan lari:
Anda akan mendapatkan di layar:
func from general
.sumber
Info lebih lanjut
sumber