Katakanlah saya memiliki skrip shell / bash test.sh
dengan nama :
#!/bin/bash
TESTVARIABLE=hellohelloheloo
./test2.sh
test2.sh
Penampilan saya seperti ini:
#!/bin/bash
echo ${TESTVARIABLE}
Ini tidak bekerja. Saya tidak ingin meneruskan semua variabel sebagai parameter karena imho ini berlebihan.
Apakah ada cara yang berbeda?
Jawaban:
Pada dasarnya Anda memiliki dua opsi:
export TESTVARIABLE
) sebelum menjalankan skrip ke-2.. test2.sh
dan akan berjalan di shell yang sama. Ini akan memungkinkan Anda berbagi variabel yang lebih kompleks seperti array dengan mudah, tetapi juga berarti bahwa skrip lain dapat memodifikasi variabel dalam shell sumber.MEMPERBARUI:
Untuk menggunakan
export
untuk mengatur variabel lingkungan, Anda dapat menggunakan variabel yang sudah ada:Ini harus bekerja di keduanya
bash
dansh
.bash
juga memungkinkan untuk digabungkan seperti:Ini juga berfungsi di saya
sh
(yang kebetulanbash
, dapat Anda gunakanecho $SHELL
untuk memeriksa). Tapi saya tidak percaya itu dijamin akan berhasilsh
, jadi sebaiknya mainkan dengan aman dan pisahkan.Setiap variabel yang Anda ekspor dengan cara ini akan terlihat dalam skrip yang Anda jalankan, misalnya:
Abu:
b.sh:
Kemudian:
Fakta bahwa keduanya adalah skrip shell juga hanya kebetulan. Variabel lingkungan dapat diteruskan ke proses apa pun yang Anda jalankan, misalnya jika kami menggunakan python, akan terlihat seperti:
Abu:
b.py:
Sumber:
Sebaliknya, kita dapat sumber seperti ini:
Abu:
b.sh:
Kemudian:
Ini lebih atau kurang "mengimpor" konten
b.sh
secara langsung dan mengeksekusi di shell yang sama . Perhatikan bahwa kami tidak perlu mengekspor variabel untuk mengaksesnya. Ini secara implisit membagikan semua variabel yang Anda miliki, serta memungkinkan skrip lain untuk menambah / menghapus / memodifikasi variabel dalam shell. Tentu saja, dalam model ini kedua skrip Anda harus bahasa yang sama (sh
ataubash
). Untuk memberi contoh bagaimana kita bisa meneruskan pesan bolak-balik:Abu:
b.sh:
Kemudian:
Ini berfungsi sama baiknya di
bash
. Ini juga memudahkan untuk berbagi data yang lebih kompleks yang tidak dapat Anda ungkapkan sebagai variabel lingkungan (setidaknya tanpa beban berat di pihak Anda), seperti array atau array asosiatif.sumber
Kesalahan fatal memberikan kemungkinan langsung: sumber skrip kedua Anda! jika Anda khawatir skrip kedua ini dapat mengubah beberapa variabel berharga Anda, Anda selalu dapat sumbernya dalam subkulit:
Tanda kurung akan membuat sumber terjadi dalam subkulit, sehingga shell induk tidak akan melihat modifikasi
test2.sh
dapat dilakukan.Ada kemungkinan lain yang harus dirujuk di sini: gunakan
set -a
.Dari referensi POSIX
set
:Dari Bash Manual :
Jadi dalam kasus Anda:
Perhatikan bahwa spesifikasi hanya menentukan bahwa dengan
set -a
variabel ditandai untuk diekspor. Itu adalah:akan bergema
c
dan bukan baris kosong ataub
(yaitu,set +a
tidak menghapus tanda untuk ekspor, juga tidak "menyimpan" nilai penugasan hanya untuk lingkungan yang diekspor). Ini, tentu saja, perilaku paling alami.Kesimpulan: menggunakan
set -a
/set +a
bisa kurang membosankan daripada mengekspor secara manual semua variabel. Ini lebih unggul daripada sumber skrip kedua, karena akan bekerja untuk perintah apa pun, tidak hanya yang ditulis dalam bahasa shell yang sama.sumber
Sebenarnya ada cara yang lebih mudah daripada mengekspor dan tidak memasang atau mencari lagi (setidaknya dalam bash, selama Anda setuju dengan mengirimkan variabel lingkungan secara manual):
biarkan a.sh menjadi
dan b.sh be
Output yang diamati adalah
Keajaiban terletak pada baris terakhir
a.sh
, di manaMessage
, hanya untuk durasi doa./b.sh
, diatur ke nilaisecret
daria.sh
. Pada dasarnya, ini seperti parameter / argumen bernama. Lebih dari itu, ia bahkan berfungsi untuk variabel seperti$DISPLAY
, yang mengontrol X Server tempat aplikasi dimulai.Ingat, panjang daftar variabel lingkungan tidak terbatas. Pada sistem saya dengan kernel vanilla yang relatif,
xargs --show-limits
memberitahu saya ukuran maksimum dari argumen buffer adalah 2094486 byte. Secara teoritis, Anda menggunakan skrip shell yang salah jika data Anda lebih besar dari itu (pipa, ada orang?)sumber
Menambah jawaban Kesalahan Fatal, Ada satu lagi cara untuk meneruskan variabel ke skrip shell lain.
Solusi yang disarankan di atas memiliki beberapa kelemahan:
using Export
: Ini akan menyebabkan variabel hadir dari ruang lingkup mereka yang bukan praktik desain yang baik.using Source
: Ini dapat menyebabkan tabrakan nama atau penulisan ulang yang tidak sengaja dari variabel yang telah ditentukan di beberapa file skrip shell lain yang merupakan sumber file lain.Ada solusi sederhana lain yang tersedia untuk kita gunakan. Mempertimbangkan contoh yang diposting oleh Anda,
test.sh
test2.sh
keluaran
Juga penting untuk dicatat bahwa
""
perlu jika kita melewati string multi-kata. Ambil satu contoh lagimaster.sh
slave1.sh
slave2.sh
keluaran
Itu terjadi karena alasan yang dijelaskan dalam tautan ini
sumber
source
sebenarnya adalah hal yang baik. Mengenai kekhawatiran Anda: menimpa secara tidak sengaja variabel yang telah ditentukan , Anda selalu dapat sumber dalam subkulit. Itu sepenuhnya menyelesaikan masalah.( . ./test2.sh )
. Tanda kurung akan membuat Bash menjalankan kontennya dalam sebuah subkulit.Di Bash jika Anda mengekspor variabel dalam subkulit, menggunakan tanda kurung seperti yang ditunjukkan, Anda menghindari bocornya variabel yang diekspor:
Keuntungannya di sini adalah bahwa setelah Anda menjalankan skrip dari baris perintah, Anda tidak akan melihat $ TESTVARIABLE bocor ke lingkungan Anda:
sumber
$
prompt perintah) tidak akan pernah melihat yang diekspor$TESTVARIABLE
. Ekspor hanya meneruskan salinan variabel ke proses anak berikutnya . Tidak mungkin untuk meneruskan variabel yang mencadangkan rantai ke proses induk kecuali dengan menyimpan nilai ke penyimpanan dan membaca penyimpanan itu nanti dalam skrip proses induk. Perpipaan ke salinan kedua dari skrip induk dimungkinkan tetapi itu bukan proses yang sama . Penjelasan yang bagus dapat ditemukan di sini .Opsi lain menggunakan
eval
. Ini hanya cocok jika senar dipercaya. Script pertama dapat mengulangi penugasan variabel:echo "VAR=myvalue"
Kemudian:
eval $(./first.sh) ./second.sh
Pendekatan ini sangat menarik ketika skrip kedua yang Anda ingin atur variabel lingkungan tidak dalam bash dan Anda juga tidak ingin
export
variabel, mungkin karena mereka sensitif dan Anda tidak ingin mereka bertahan.sumber
Cara lain, yang sedikit lebih mudah bagi saya adalah dengan menggunakan pipa bernama. Named pipes menyediakan cara untuk menyinkronkan dan mengirim pesan di antara berbagai proses.
Memalukan:
B. bash:
Pemakaian:
B.bash akan menunggu pesan dan segera setelah A.bash mengirim pesan, B.bash akan melanjutkan pekerjaannya.
sumber