Saya mendefinisikan skrip shell yang harus source
dieksekusi oleh pengguna.
Apakah ada cara konvensional atau cerdas untuk memberi petunjuk kepada pengguna bahwa ini adalah kasusnya, misalnya melalui ekstensi file?
Apakah ada kode shell yang dapat saya tulis di file itu sendiri, yang akan menyebabkannya mengulangi pesan dan berhenti jika dieksekusi alih-alih bersumber, sehingga saya dapat membantu pengguna menghindari kesalahan yang jelas ini?
x
, yang hanya berisi perintah. your-script-to-be-sourced
, tidak apa-apa, tetapi jika ia ingin mengeksekusinyabash your-script-to-be-sourced
harus dilarang? Apa gunanya pembatasan ini?env
variabel dan membiarkannya sebagai output skrip de facto . Seorang pemula akan terjebak selama berhari-hari dengan teka-teki jika Anda membiarkan mereka mengeksekusi.if __name__ == '__main__'
?Jawaban:
Dengan asumsi bahwa Anda menjalankan bash, letakkan kode berikut di dekat awal skrip yang ingin Anda gunakan tetapi tidak dijalankan:
Di bawah bash,
${BASH_SOURCE[0]}
akan berisi nama file saat ini yang dibaca oleh shell terlepas dari apakah itu bersumber atau dieksekusi.Sebaliknya,
$0
adalah nama file saat ini sedang dieksekusi.-ef
menguji apakah kedua file ini adalah file yang sama. Jika ya, kami memperingatkan pengguna dan keluar.Baik
-ef
atauBASH_SOURCE
yang POSIX. Sementara-ef
didukung oleh ksh, yash, zsh dan Dash,BASH_SOURCE
membutuhkan bash. Dalamzsh
Namun,${BASH_SOURCE[0]}
bisa diganti oleh${(%):-%N}
.sumber
echo "Usage: source \"$myfile\""
source
tidak portabel. Mempertimbangkan bahwa jawaban ini khusus untuk bash, ini tidak terlalu buruk, tetapi kebiasaan yang baik untuk menggunakan portable.
File yang tidak dapat dieksekusi dapat bersumber tetapi tidak dieksekusi, jadi, sebagai garis pertahanan pertama, tidak menetapkan bendera yang dapat dieksekusi harus menjadi petunjuk yang baik ...
Sunting: trik Saya baru saja menemukan: membuat shebang menjadi executable yang bukan shell interpreter,
/bin/false
membuat skrip mengembalikan kesalahan (rc! = 0)sumber
bash somefile.sh
...bash
(vd perl, python, awk ...), maka Anda telah melihat sumbernya dan melihat komentar yang mengatakan untuk tidak melakukannya :)somefile.pl
dan Python sebagaisomefile.py
, jadi tidak, saya mungkin belum membaca komentar (apa itu, bahkan, tetap?) Danbash somefile.sh
lebih pendek untuk mengetik daripadachmod +x somefile.sh; ./somefile.sh
...bash
, pertama-tama akan mencobaexecve
suatu file, tetapi jika gagal, mereka memeriksa file secara manual dan menafsirkan secara manual#!
dan memintanya melalui penerjemah itu: ini adalah warisan dari hari-hari ketika ruang#!
itu murni ruang pengguna konvensi, alih-alih ditangani oleh kernel itu sendiri. Saya pikirbash
, setidaknya, tidak akan melakukan ini untuk file yang tidak dapat dieksekusi, tapi saya tidak tahu apakah itu portabel untuk mengharapkan perilaku yang waras dari semua shell sehingga pengguna mungkin akan meminta script.bash
dan itubash script.sh
bisa berbahaya.Ada beberapa metode yang disarankan dalam posting Stack Overflow ini , di antaranya, saya menyukai yang berbasis fungsi yang disarankan oleh Wirawan Purwanto dan mr.spuratic best:
Jadi, Anda dapat menambahkan ke awal skrip:
sumber
Anggap saja tidak ada gunanya, daripada merusak, untuk mengeksekusi skrip, Anda dapat menambahkan
sampai akhir skrip.
return
di luar fungsi memiliki kode keluar non-nol kecuali file tersebut bersumber.sumber
return 2>/dev/null; echo "$0: This script must be sourced" 1>&2; exit 1
Saat Anda mendapatkan skrip shell, garis shebang diabaikan. Dengan memasukkan shebang yang tidak valid, Anda dapat memberi tahu pengguna bahwa skrip itu dieksekusi dengan keliru:
Pesan kesalahannya adalah ini:
Nama argumen (sewenang-wenang) sudah memberikan petunjuk yang kuat, tetapi pesan kesalahan masih belum 100% jelas. Kami dapat memperbaikinya dengan skrip utilitas
source-this-script
yang ditempatkan di suatu tempat di AndaPATH
:Sekarang, pesan kesalahannya adalah ini:
Perbandingan dengan pendekatan lain
Dibandingkan dengan jawaban lain, pendekatan ini hanya memerlukan perubahan minimal untuk setiap skrip (dan memiliki garis shebang membantu dengan deteksi tipe file di editor dan menentukan dialek skrip shell, sehingga bahkan ada manfaatnya). Kelemahannya adalah pesan kesalahan yang agak tidak jelas, atau penambahan (satu kali) dari skrip shell lain.
Itu tidak mencegah permintaan eksplisit melalui
bash path/to/script.sh
, (terima kasih @muru!).sumber
bash some/script.sh
, yang juga akan mengabaikan shebang.#!/bin/echo 'You must source this script!'
atau semacamnya.