Apa cara terbaik untuk mendeteksi (dari skrip) apakah perangkat lunak diinstal?

9

Saya sudah frustrasi sebelumnya dengan perbedaan dalam output dari whichperintah di berbagai platform yang berbeda (Linux vs Solaris vx. OS X), dengan cangkang yang berbeda mungkin memainkan masalah ini juga. typetelah disarankan sebagai alternatif yang lebih baik, tetapi seberapa portabel hal itu?

Di masa lalu saya telah menulis fungsi yang mem-parsing keluaran whichdan menangani berbagai kasus penggunaan yang saya alami. Mereka bekerja di mesin yang saya gunakan, dan begitu juga untuk skrip pribadi saya, tetapi ini tampaknya sangat tidak dapat diandalkan untuk perangkat lunak yang akan saya posting di suatu tempat untuk digunakan orang lain.

Untuk mengambil satu contoh saja, misalkan saya harus mendeteksi dari skrip apakah bash dan zsh tersedia pada mesin, dan kemudian jalankan perintah dengan zsh jika ada, dan dengan bash jika zsh tidak dan bash sudah mencukupi versi untuk tidak memiliki bug tertentu. Sebagian besar skrip lainnya bisa berupa Bourne shell atau Ruby atau apa pun, tetapi yang satu ini harus dilakukan (AFAIK) dengan zsh atau versi bash terbaru.

Dapatkah saya mengandalkan typeketersediaan di berbagai platform? Apakah ada alternatif lain whichyang dapat dengan mudah dan konsisten menjawab pertanyaan apakah perangkat lunak tertentu diinstal?

(Jika Anda ingin juga memberikan ide-ide khusus yang terkait dengan contoh yang saya berikan, itu bagus, tapi saya terutama hanya bertanya tentang kasus umum: apa cara yang paling dapat diandalkan untuk mencari tahu apakah suatu hal tertentu dipasang pada mesin yang diberikan ?)

iconoclast
sumber

Jawaban:

10

Di abad ke-21, terutama jika Anda menargetkan mesin yang cenderung memiliki bash atau zsh, Anda dapat mengandalkannya type. (Itu tidak ada di unices yang sangat lama, seperti pada, dari tahun 1970-an atau awal 1980-an.) Anda tidak dapat mengandalkan output yang berarti apa-apa, tetapi Anda dapat mengandalkan pengembaliannya 0 jika ada perintah dengan nama itu dan bukan nol sebaliknya.

whichtidak standar dan tidak dapat diandalkan dalam praktiknya . typeadalah alternatif yang disarankan. whereismenderita masalah yang sama seperti whichdan kurang umum. whencekhusus untuk ksh dan zsh.

Jika memungkinkan, akan lebih andal untuk menguji keberadaan perintah dan menguji apakah perilakunya terlihat masuk akal. Misalnya, uji keberadaan versi bash yang sesuai dengan menjalankan bash -c 'somecommand', mis

# Test for the `-v` operator (which appeared in bash 4.2)
if bash -c 'test -v HOME' 2>/dev/null; then 

Hari ini Anda dapat mengandalkan hampir semua yang ada di Singe UNIX spesifikasi versi 2 (kecuali untuk barang-barang eksotis seperti Fortran dan SCCS, yang merupakan opsional). Anda dapat mengandalkan sebagian besar versi 3 , tetapi ini belum sepenuhnya diterapkan di mana-mana. Dukungan Versi 4 lebih sketsa. Jika Anda akan membaca spesifikasi ini, saya sarankan membaca versi 3, yang jauh lebih mudah dibaca dan kurang ambigu daripada versi 2.

Untuk contoh tentang cara mendeteksi kekhususan sistem, lihat autoconf dan configureskrip berbagai perangkat lunak.

Lihat juga Sumberdaya untuk pemrograman shell portabel untuk tips lebih lanjut.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
Ini dapat mengambil manfaat dari ekspansi untuk mengomentari teknik yang umum direkomendasikan menggunakan hashdan command -v.
Caleb
@ Caleb Untuk tujuan pertanyaan ini, saya tidak melihat manfaat command -vlebih type, semua yang kita butuhkan adalah hasil boolean. Apa "teknik yang umum direkomendasikan menggunakan hash" yang Anda maksud?
Gilles 'SANGAT berhenti menjadi jahat'