shebang dan jalan

22

Mengapa seorang shebang membutuhkan jalan?

Salah

#!ruby

Benar

#!/usr/local/bin/ruby

#!/usr/bin/env ruby

Sistem operasi harus memiliki informasi mengenai lintasan untuk perintah terdaftar, dan mengapa masih mengharapkannya diberikan?

sawa
sumber

Jawaban:

22

Mungkin untuk menjaga agar kernel lebih sederhana. Saya tidak berpikir kernel pernah mencari jalan Anda untuk menemukan executable. Itu ditangani oleh perpustakaan C. #!pemrosesan dilakukan di kernel, yang tidak menggunakan pustaka C standar.

Juga, saya tidak berpikir kernel memiliki gagasan tentang apa path Anda. $PATHadalah variabel lingkungan, dan hanya proses yang memiliki lingkungan. Kernel tidak. Saya kira itu bisa mengakses lingkungan proses yang melakukan exec, tapi saya tidak berpikir apa pun saat ini di kernel pernah mengakses variabel lingkungan seperti itu.

cjm
sumber
5

Anda bisa mendapatkan PATH-menggunakan semantik menggunakan env, jadi:

#!/usr/bin/env ruby  

memiliki semantik yang Anda inginkan

#!ruby

Alasan yang bergantung pada PATHtidak dianggap praktik yang baik adalah bahwa skrip tidak dapat membuat asumsi tentang konten variabel lingkungan PATH, melanggar "model ketergantungan berurutan" dari biner di mana

  1. /bin berisi file executable yang dibutuhkan saat boot;
  2. /usr/bin berisi file executable lain yang digunakan oleh instalasi OS;
  3. /usr/local/bin berisi executable yang diinstal oleh administrator sistem yang bukan bagian dari OS dasar.
  4. ~/bin berisi file executable milik pengguna.

Setiap level tidak boleh mengasumsikan keberadaan binari kemudian dalam urutan, yang lebih "aplikasi" tetapi mungkin bergantung pada binari sebelumnya, yang lebih "mendasar". Dan variabel PATH cenderung berjalan dari aplikasi ke fundamental, yang merupakan arah yang berlawanan dengan ketergantungan alami di atas.

Untuk mengilustrasikan masalah, tanyakan pada diri sendiri apa yang terjadi jika sebuah skrip ~/binmemanggil skrip /usr/local/binyang memanggil Ruby? Haruskah skrip itu bergantung pada versi yang diinstal OS pada /usr/bin/ruby, atau pada salinan pribadi yang kebetulan dimiliki oleh pengguna ~/bin/ruby? PATHpencarian memberikan semantik tak terduga yang terkait dengan yang terakhir (mungkin ~/bin/rubymerupakan tautan simbolis yang rusak), sambil memanggang di jalur untuk #!memberikan yang pertama.

Sebenarnya tidak ada "sistem operasi ... platform-independen informasi tentang jalur untuk perintah terdaftar", jadi hal yang paling sederhana adalah bersikeras jalur yang disediakan di #!.

Charles Stewart
sumber
0

Saya percaya itu sehingga Anda dapat menentukan penerjemah alternatif jika Anda butuh atau mau. Sebagai contoh:

#!/home/user/myrubyinterpreter

Lebih sering terlihat dengan skrip shell:

#!/bin/bash
#!/bin/sh
#!/bin/dash
#!/bin/csh
Andrew Lambert
sumber
4
Tetapi mengapa itu membuatnya perlu? Anda dapat menjalankan ruby ​​secara langsung ruby, tetapi itu tidak menghentikan Anda untuk menentukan /home/user/myrubyinterpreterjika Anda mau
Michael Mrozek
Maksud Michael adalah apa yang saya minta.
sawa
0

Dari buku Classic Shell Scripting :

Skrip shell biasanya dimulai dengan #! /bin/sh. Gunakan path ke shell yang sesuai dengan POSIX jika Anda /bin/shtidak mematuhi POSIX. Ada juga beberapa "gotcha" tingkat rendah yang harus diperhatikan:

  • Anda harus mengetahui pathname lengkap untuk penerjemah yang akan dijalankan. Ini dapat mencegah portabilitas cross-vendor, karena vendor yang berbeda meletakkan barang-barang di tempat yang berbeda (misalnya, /bin/awkversus /usr/bin/awk).
Arturo Herrero
sumber
-2

Ada alasan lain, tetapi dari sudut pandang keamanan saya tidak akan pernah ingin skrip membuat asumsi tentang jalur yang benar. Bagaimana jika itu salah dan menjalankan shell atau penerjemah yang salah? Salah satu yang telah dimasukkan oleh pengguna jahat? Atau bagaimana jika itu bergantung pada shell tertentu dan akan crash jika shell yang salah digunakan?

Pengguna mungkin dipusingkan dengan jalur mereka dan memecahkan barang - jangan percayai pengguna :-) Saya telah melakukan banyak serangan yang bergantung pada pengguna melakukan hal yang salah dengan jalur mereka - biasanya mendapatkan sesuatu dalam urutan yang salah - sehingga saya dapat menumbangkan panggilan skrip normal.

Ya, saya tahu jika Anda sendiri yang menulis skrip, Anda dapat mengklaim bahwa Anda telah menyortir jalan Anda sendiri, tetapi seorang penerjemah tidak dapat membuat keputusan itu.

Rory Alsop
sumber
Kekhawatiran ini hanya berlaku jika skrip dijalankan dengan hak istimewa yang ditinggikan. Dan itu tidak biasa, karena shebang dan setxid tidak bermain bersama dengan baik, dan ada banyak hal yang perlu dikhawatirkan daripada $PATH. . Tanpa hak yang lebih tinggi, bagaimana jika LD_PRELOADdigunakan? PS Downvoted karena memberikan peringatan palsu tentang keamanan merugikan keamanan.
Gilles 'SO- stop being evil'
Maksud Anda tentang setxid adalah valid, namun itu adalah vektor serangan yang sangat berguna jadi jelas bukan peringatan yang salah
Rory Alsop
1
Bisakah Anda memberikan contoh kasus di mana PATHvektor serangan, dan tidak ada banyak vektor serangan lain sehingga seluruh pendekatan harus dipikirkan kembali?
Gilles 'SANGAT berhenti menjadi jahat'
@Gilles - +1 Anda memiliki poin bagus, pasti, seolah-olah ini rusak mungkin ada cara lain yang sama validnya, namun dalam hal hal-hal yang rusak dapat Anda perbaiki, ini mudah.
Rory Alsop