Mengacu pada file yang berhubungan dengan menjalankan skrip

97

Dalam skrip bash yang saya tulis, saya gunakan sourceuntuk menyertakan variabel yang ditentukan dalam file konfigurasi. Script yang akan dieksekusi adalah act.sh, sedangkan script yang harus sourced adalah act.conf.sh, maka di dalam act.shsaya ada:

source act.conf.sh

Namun ini hanya berfungsi ketika berjalan act.shdi direktori yang berisi itu, karena act.conf.shmerujuk ke file yang ditempatkan di bawah direktori kerja. Apakah ada solusi untuk membuatnya merujuk ke file yang terkait dengan skrip yang sedang dijalankan tanpa meminta cd? Terima kasih.

Ryan Li
sumber

Jawaban:

121

Lihat: entri FAQ BASH # 28: "Bagaimana cara menentukan lokasi skrip saya? Saya ingin membaca beberapa file konfigurasi dari tempat yang sama."

Solusi apa pun tidak akan berhasil 100% setiap saat:

Penting untuk disadari bahwa dalam kasus umum, masalah ini tidak ada solusinya. Pendekatan apa pun yang mungkin pernah Anda dengar, dan pendekatan apa pun yang akan dirinci di bawah ini, memiliki kekurangan dan hanya akan berfungsi dalam kasus tertentu. Pertama dan terpenting, cobalah untuk menghindari masalah sepenuhnya dengan tidak bergantung pada lokasi skrip Anda!

Jika Anda perlu menulis alat yang sangat dapat digunakan kembali, maka mengambil jalur yang benar sebagai parameter ke skrip Anda akan menjadi metode yang paling dapat diandalkan .

Dengan asumsi skrip Anda hanya akan dijalankan dari cangkang tertentu, dan hanya dengan sedikit fleksibilitas yang diperlukan, Anda mungkin dapat melonggarkan beberapa paranoia ini. Masih bagus untuk melihat pilihan Anda. Ada pola umum yang digunakan orang yang sangat bermasalah.

Secara khusus, FAQ merekomendasikan untuk menghindari $0variabel yang sangat umum digunakan :

Tidak ada yang membaca $0akan menjadi antipeluru, karena $0itu sendiri tidak dapat diandalkan.

Sebagai alternatif, Anda bisa menggunakan $BASH_SOURCE. Sesuatu seperti ini:

source "${BASH_SOURCE%/*}/act.conf.sh"

Ada beberapa peringatan untuk solusi ini juga. Lihat halaman FAQ untuk melihat trade-off antara solusi yang berbeda. Mereka tampaknya merekomendasikan cddalam kombinasi dengan $BASH_SOURCEkasus di mana itu akan bekerja untuk Anda, karena Anda mendapatkan kondisi kesalahan yang berguna ketika gagal berkembang dengan benar.

Ignacio Vazquez-Abrams
sumber
1
Terima kasih, saya akan menggunakan readlink. Tidak dapat menentukan kata kunci yang akan dicari jadi kirimkan pertanyaannya di sini ....
Ryan Li
9
Bisakah Anda memasukkan info yang relevan ke dalam jawaban seandainya faq bash turun?
Merlyn Morgan-Graham
3
Link merekomendasikan :,cd "${BASH_SOURCE%/*}" || exit atau read somevar < "${BASH_SOURCE%/*}/etc/somefile", Link Strongly Discourages $0 "Tidak ada yang bertuliskan $ 0 yang tahan peluru, karena $ 0 itu sendiri tidak dapat diandalkan."
ThorSummoner
10
Apa fungsi% / * setelah BASH_SOURCE dan bagaimana caranya?
Silicomancer
34

Lihat ini: Bash: Bagaimana _best_ menyertakan skrip lain?

Saya menyarankan untuk menggunakan:

source $(dirname $0)/act.conf.sh
vagovszkym.dll
sumber
8
Ini bukanlah jawaban yang Anda cari. $0secara inheren buggy. Lihat jawaban yang dipilih dan diterima teratas untuk alasannya, atau cukup baca mywiki.wooledge.org/BashFAQ/028 - solusi singkat untuk pertanyaan yang diajukan adalah sepertisource "${BASH_SOURCE%/*}/act.conf.sh"
Merlyn Morgan-Graham
5

Coba yang berikut ini:

source ${BASH_SOURCE[0]/%act.sh/act.conf.sh}
Tidak mengerti
sumber
1

Saya biasanya, menambahkan ini di atas skrip saya.

cd $(dirname $BASH_SOURCE)

Kemudian, semua kode berikutnya dieksekusi relatif terhadap jalur skrip tersebut.

Gayan Weerakutti
sumber