Saya sedang memprogram skrip shell Linux yang akan mencetak status banner selama pelaksanaannya hanya jika alat yang tepat, katakanlah figlet
, diinstal (ini: dapat dijangkau di jalur sistem ).
Contoh:
#!/usr/bin/env bash
echo "foo"
figlet "Starting"
echo "moo"
figlet "Working"
echo "foo moo"
figlet "Finished"
Saya ingin untuk naskah saya bekerja tanpa kesalahan bahkan ketika figlet
sedang tidak diinstal .
Apa yang bisa menjadi metode praktis ?
shell
scripting
executable
Sopalajo de Arrierez
sumber
sumber
figlet ... || true
.figlet || true
, tetapi dalam kasus Anda mungkin fungsi shell yang tidak dapat dicetak.Jawaban:
Interpretasi saya akan menggunakan fungsi pembungkus bernama sama dengan alat; dalam fungsi itu, jalankan alat nyata jika ada:
Maka Anda bisa
figlet arg1 arg2...
tidak mengubah skrip Anda.@Olorin datang dengan metode yang lebih sederhana: tentukan fungsi wrapper hanya jika kita perlu (jika alat tidak ada):
Jika Anda ingin argumen yang
figlet
akan dicetak bahkan jika figlet tidak diinstal, sesuaikan saran Olorin sebagai berikut:sumber
command
? Saya tidak memilikinya di instalasi saya (Red Hat 6.8 Enterprise dan Cygwin64).command
adalah built-in POSIX Bourne shell. Ini biasanya mengeksekusi perintah yang diberikan, tetapi-v
flag membuatnya berperilaku lebih sepertitype
, shell lain builtin.type -a command
akan menunjukkan kepada Anda. hanyawhich
akan menampilkan file yang dapat dieksekusi pada Anda , bukan bawaan, kata kunci, fungsi, atau alias.$PATH
which
tidak menemukan alias yang berlaku, karena aliaswhich
sendiri untuk menjalankan/usr/bin/which
dan pipa itu daftar alias shell untuk melihat (!) (Tentu saja\which
menekan alias dan hanya menggunakan program, yang tidak menunjukkan alias.)Anda dapat menguji apakah
figlet
adasumber
Cara umum untuk melakukan ini adalah dengan
test -x
alias[ -x
. Berikut ini contoh yang diambil dari/etc/init.d/ntp
sistem Linux:Varian ini bergantung pada mengetahui path lengkap dari executable. Dalam
/bin/lesspipe
saya menemukan contoh yang bekerja di sekitar itu dengan menggabungkan-x
danwhich
perintah:Cara ini akan bekerja tanpa mengetahui terlebih dahulu mana di
PATH
dalambunzip
executable adalah.sumber
which
. Dan bahkan jikawhich
berhasil, menggunakantest -x
pada outputnya konyol: jika Anda mendapatkan jalan dariwhich
, itu ada.test -x
tidak lebih dari sekadar memeriksa apakah ada file (untuk itulahtest -e
). Itu juga memeriksa apakah file telah menetapkan izin eksekusi.which
.Di awal skrip Anda, periksa apakah
figlet
ada, dan jika tidak, tentukan fungsi shell yang tidak melakukan apa-apa:type
memeriksa apakahfiglet
ada sebagai built-in shell, fungsi, alias, atau kata kunci,>/dev/null 2>&1
membuang stdin dan stdout sehingga Anda tidak mendapatkan output, dan jika tidak ada,figlet() { :; }
mendefinisikanfiglet
sebagai fungsi yang tidak melakukan apa-apa.Dengan cara ini Anda tidak perlu mengedit setiap baris skrip yang digunakan
figlet
, atau memeriksa apakah ada setiap kalifiglet
dipanggil.Anda dapat menambahkan pesan diagnostik, jika Anda suka:
Sebagai bonus, karena Anda tidak menyebutkan shell mana yang Anda gunakan, saya percaya ini adalah POSIX compliant, jadi itu harus bekerja pada sebagian besar shell.
sumber
type figlet >/dev/null 2>&1
denganhash figlet 2>/dev/null
jika Anda menggunakan bash. (OP mengatakan "jika itu ada di PATH saya".)Alternatif lain - pola yang saya lihat di skrip konfigurasi proyek otomatis:
Dalam kasus spesifik Anda, Anda bahkan dapat melakukannya,
Jika Anda tidak tahu jalur spesifik, Anda dapat mencoba beberapa
elif
(lihat di atas) untuk mencoba lokasi yang diketahui, atau cukup gunakanPATH
untuk selalu menyelesaikan perintah:Secara umum, saat menulis skrip, saya lebih suka hanya memanggil perintah di lokasi tertentu yang ditentukan oleh saya. Saya tidak suka ketidakpastian / risiko apa yang mungkin dimasukkan pengguna akhir ke dalam mereka
PATH
, mungkin di mereka sendiri~/bin
.Jika, misalnya, saya menulis skrip yang rumit untuk orang lain yang mungkin menghapus file berdasarkan output dari perintah tertentu yang saya panggil, saya tidak ingin secara tidak sengaja mengambil sesuatu di dalamnya
~/bin
yang mungkin atau mungkin bukan perintah Saya mengharapkan.sumber
figlet
ada di dalam/usr/local/bin
atau/home/bob/stuff/programs/executable/figlet
?type
Perintah bash menemukan perintah, fungsi, alias, kata kunci, atau builtin (lihathelp type
) dan mencetak lokasi atau definisi. Itu juga mengembalikan kode kembali yang mewakili hasil pencarian; true (0) jika ditemukan. Jadi yang kami lakukan di sini adalah mencoba menemukanfiglet
di jalur (-p
berarti hanya mencari file, bukan built-in atau fungsi, dan juga menekan pesan kesalahan), membuang output (itulah yang> /dev/null
dilakukan), dan jika itu mengembalikan true (&&
) , itu akan dieksekusifiglet
.Ini lebih sederhana jika
figlet
berada di lokasi tetap:Di sini kita menggunakan
test
perintah (alias[
) untuk melihat apakah/usr/bin/figlet
dieksekusi (-x
) dan jika demikian (&&
) jalankan. Solusi ini saya pikir lebih portabel daripada menggunakantype
yang merupakan bashism yang saya percayaAnda bisa membuat fungsi yang melakukan ini untuk Anda:
(Kutipan diperlukan karena ruang potensial)
Maka Anda hanya akan melakukan:
sumber
o /, aku akan mengatakan sesuatu seperti
sumber
Anda dapat melakukan eksekusi pengujian, menekan output apa pun, dan menguji kode keberhasilan / kegagalan. Pilih argumen untuk figlet untuk membuat tes ini tidak mahal. -? atau --help atau --version adalah kemungkinan yang jelas.
Ditambahkan dalam menanggapi komentar di bawah ini: jika Anda benar-benar ingin menguji figlet yang ada, bukan bahwa itu dapat digunakan, maka Anda akan melakukan
sumber
$?
sama dengan 127 (pada sistem linux saya). 127 adalah "perintah tidak ditemukan". Tetapi pemikiran saya adalah bahwa untuk perintah rasional, jikacommand --help
gagal, maka instalasinya cukup jelas sehingga mungkin tidak ada di sana !.--help
ketersediaan. Utilitas Posix tidak memilikinya, salah satunya, dan pedoman posix sebenarnya merekomendasikannya .at --help
gagal denganat: invalid option -- '-'
, misalnya, dan status keluar130
di sistem saya.-?
--help
--version
... atau Anda bisa mengetahui apa yangfiglet -0 --illegal
keluar, dan memperlakukannya sebagai indikator keberhasilan Anda (asalkan bukan 127, yang akan saya klasifikasikan sebagai sabotase).