Untuk pertanyaan ini, mari kita pertimbangkan skrip shell bash, meskipun pertanyaan ini harus berlaku untuk semua jenis skrip shell.
Ketika seseorang mengeksekusi skrip shell, apakah Linux memuat semua skrip sekaligus (ke dalam memori mungkin) atau apakah ia membaca perintah skrip satu per satu (baris demi baris)?
Dengan kata lain, jika saya menjalankan skrip shell dan menghapusnya sebelum eksekusi selesai, apakah eksekusi akan dihentikan atau apakah akan berlanjut seperti itu?
linux
shell
shell-script
Pengguna Terdaftar
sumber
sumber
Jawaban:
Jika Anda menggunakan,
strace
Anda dapat melihat bagaimana skrip shell dijalankan ketika dijalankan.Contoh
Katakanlah saya punya skrip shell ini.
Menjalankannya menggunakan
strace
:Melihat ke dalam
strace.log
file mengungkapkan hal berikut.Setelah file dibaca, file itu dieksekusi:
Pada contoh di atas kita dapat dengan jelas melihat bahwa seluruh skrip tampaknya sedang dibaca sebagai satu kesatuan, dan kemudian dieksekusi di sana setelahnya. Jadi itu akan "muncul" setidaknya dalam kasus Bash bahwa ia membaca file, dan kemudian menjalankannya. Jadi, Anda akan berpikir Anda dapat mengedit skrip saat sedang berjalan?
CATATAN: Namun, jangan! Baca terus untuk memahami mengapa Anda tidak boleh main-main dengan file skrip yang berjalan.
Bagaimana dengan penerjemah lain?
Tapi pertanyaan Anda agak tidak jelas. Bukan Linux yang seharusnya memuat konten file, itu adalah penerjemah yang memuat konten, jadi terserah bagaimana penerjemah mengimplementasikan apakah itu memuat file seluruhnya atau dalam blok atau baris sekaligus.
Jadi mengapa kita tidak bisa mengedit file?
Jika Anda menggunakan skrip yang jauh lebih besar namun Anda akan melihat bahwa tes di atas agak menyesatkan. Bahkan sebagian besar penerjemah memuat file mereka dalam blok. Ini cukup standar dengan banyak alat Unix tempat mereka memuat blok file, memprosesnya, dan kemudian memuat blok lain. Anda dapat melihat perilaku ini dengan T&J T&J yang saya tulis beberapa waktu lalu mengenai
grep
, berjudul: Berapa banyak teks yang dikonsumsi grep / egrep setiap kali? .Contoh
Katakanlah kita membuat skrip shell berikut.
Menghasilkan file ini:
Yang berisi jenis konten berikut:
Sekarang ketika Anda menjalankan ini menggunakan teknik yang sama di atas dengan
strace
:Anda akan melihat bahwa file sedang dibaca dengan kenaikan 8KB, jadi Bash dan shell lainnya kemungkinan tidak akan memuat file secara keseluruhan, melainkan membacanya dalam bentuk blok.
Referensi
sumber
Ini lebih tergantung shell daripada tergantung OS.
Tergantung pada versinya,
ksh
baca skrip on demand dengan blok 8k atau 64k byte.bash
baca skrip baris demi baris. Namun, mengingat garis fakta bisa panjang sewenang-wenang, itu membaca setiap kali 8176 byte dari awal baris berikutnya menjadi parse.Ini untuk konstruksi sederhana, yaitu serangkaian perintah sederhana.
Jika perintah terstruktur shell digunakan ( kasus jawaban yang diterima tidak dapat dipertimbangkan ) seperti
for/do/done
loop,case/esac
switch, dokumen di sini, subkulit yang terlampir oleh tanda kurung, definisi fungsi, dll. Dan kombinasi apa pun di atas, penerjemah shell membaca ke akhir konstruksi untuk memastikan terlebih dahulu tidak ada kesalahan sintaksis.Ini agak tidak efisien karena kode yang sama dapat dibaca berulang kali dalam jumlah besar tetapi dimitigasi oleh fakta bahwa konten ini biasanya di-cache.
Apa pun penerjemah shell, sangat tidak bijaksana untuk memodifikasi skrip shell ketika sedang dieksekusi karena shell bebas untuk membaca lagi setiap bagian skrip dan ini dapat menyebabkan kesalahan sintaksis yang tidak terduga jika tidak sinkron.
Perhatikan juga bahwa bash mungkin macet dengan pelanggaran segmentasi ketika tidak dapat menyimpan konstruksi skrip yang terlalu besar yang bisa dibaca oleh ksh93 dengan sempurna.
sumber
Itu tergantung pada bagaimana penerjemah yang menjalankan skrip bekerja. Semua yang dilakukan kernel adalah memperhatikan file yang akan dijalankan dimulai
#!
, pada dasarnya menjalankan sisa baris sebagai sebuah program dan memberikannya file executable sebagai argumen. Jika penerjemah yang terdaftar di sana membaca file itu baris demi baris (seperti shell interaktif lakukan dengan apa yang Anda ketik), itulah yang Anda dapatkan (tetapi struktur multi-line loop dibaca dan disimpan untuk pengulangan); jika penerjemah mencabut file ke dalam memori, memprosesnya (mungkin mengkompilasinya ke representasi perantara, seperti Perl dan Pyton lakukan) file tersebut dibaca secara penuh sebelum dieksekusi.Jika Anda menghapus file sementara itu, file tersebut tidak dihapus sampai juru bahasa menutupnya (seperti biasa, file hilang ketika referensi terakhir, baik itu entri direktori atau proses menjaganya tetap terbuka) menghilang.
sumber
File 'x':
Lari:
IIRC file tidak dihapus selama proses tetap terbuka. Penghapusan hanya menghapus DIRENT yang diberikan.
sumber