Bisakah saya memodifikasi file skrip bash (.sh) saat sedang berjalan?

28

Misalkan saya memiliki skrip script.sh, yang membutuhkan waktu untuk dieksekusi. Saya melaksanakannya ./script.sh,. Ketika sedang berjalan di jendela terminal, saya memodifikasi file script.sh. Apakah ini akan berpengaruh pada proses yang sudah berjalan?

Setelah memodifikasinya, saya menjalankan file yang dimodifikasi, jadi saya memiliki dua proses yang berjalan sekarang. Apakah ini baik?

becko
sumber
2
mirip dengan unix.stackexchange.com/q/121013/55673 di U&L
Pengguna Terdaftar

Jawaban:

36

Ketika Anda membuat perubahan pada skrip Anda, Anda membuat perubahan pada disk (hard disk - penyimpanan permanen); saat Anda menjalankan skrip, skrip dimuat ke memori Anda (RAM).

Jadi, perubahan yang Anda buat pada skrip tidak akan memengaruhi skrip yang sedang berjalan, itu akan menjalankan versi yang Anda jalankan sebelum membuat perubahan itu.

Namun, ketika Anda menjalankan skrip yang diubah lagi tanpa menghentikan instance yang berjalan sebelumnya, akan ada dua contoh skrip - yang memiliki perubahan dan yang lama.

Berhati-hatilah bahwa sumber daya yang digunakan dan dimodifikasi oleh skrip akan bertentangan. Misalnya, jika Anda memodifikasi file menggunakan skrip, skrip yang berjalan nanti tidak akan dapat membuka file itu untuk ditulis dan gagal dieksekusi dengan benar.

Pembaruan: Terima kasih kepada Pengguna Terdaftar untuk mengarahkan saya ke jawaban yang lebih baik di Unix.stackexchange.com.

Bergantung pada ukuran skrip dan kompiler / penerjemah yang dimaksud, skrip dimuat sebagian / sepenuhnya. Jadi, jika skrip tidak dimuat sepenuhnya, perubahan yang Anda buat pada skrip Anda akan mencerminkan instance yang berjalan setelah bagian skrip dimuat ke dalam memori.

Jadi, tidak disarankan untuk mengubah skrip Anda pada disk yang saat ini berjalan untuk hasil yang tidak dapat diprediksi: Pertama hentikan instance yang berjalan dan kemudian modifikasi skrip Anda dan kemudian jalankan kembali skrip tersebut.

pekerjaan
sumber
11
Bukan jawaban yang sempurna, baca unix.stackexchange.com/q/121013/55673
Pengguna Terdaftar
@registereduser: oh ya, pertanyaan itu hanya mengingatkan saya pada pelajaran OS saya. Akan mengedit jawaban saya segera setelah saya mendapatkan ke desktop saya (di ponsel saya sekarang)
jobin
Saya kira untuk skrip pendek seharusnya tidak ada masalah.
becko
1
Ketika saya mencoba ini dengan bash v3.2.48 (lihat di sini ), itu tidak buffer melampaui akhir baris (dan gagal ketika saya memodifikasi skrip saat dijalankan). Saya baru saja menguji ulang dengan bash v4.3.0, dan buffered seluruh skrip (pendek). Jadi ... Saya tidak akan mengandalkan perilaku tertentu.
Gordon Davisson
1
@RegisteredUser Tidak dengan semua versi bash - lihat contoh yang saya tautkan.
Gordon Davisson
4

Saya akan menambahkan sesuatu yang saya pikir belum dikatakan dalam jawaban lain. Banyak tergantung pada bagaimana Anda mengedit file. Melakukan echo "stuff" >filedari shell (contoh lain) memang akan menimpa file, saya pikir. Tetapi jika Anda mengedit file dengan misalnya emacsdan kemudian menyimpan, ini tidak akan terjadi. Alih-alih di sini, editor mengganti nama file lama ke beberapa nama cadangan (mungkin sebenarnya menghapus cadangan sebelumnya), dan kemudian menulis konten buffer yang dimodifikasi sebagai file baru dengan nama lama (sekarang sudah dikerjakan) . Karena shell (atau penerjemah lain) yang membaca skrip hampir pasti akan membuka file hanya sekali, setelah itu tidak tergantung pada keberadaan nama file., itu hanya terus membaca file disk fisik (diidentifikasi oleh nomor inode) yang dikaitkan dengan nama file pada saat pembukaan. Jadi, bahkan jika itu membaca skrip dalam blok (yang akan menjadi solusi termudah jika menggunakan buffered text I / O), itu akan terus membaca baris dari contoh file lama, yang kemungkinan tidak akan berubah dengan mengedit Anda.

Marc van Leeuwen
sumber
+1 Saya menggunakan Sublime Text sebagai editor saya. Apakah Anda tahu jika itu juga mengubah nama file emacs?
becko
1
Saya pikir sebagian besar editor akan menggunakan skema penggantian nama (bahkan jika mereka seharusnya tidak menyimpan versi cadangan) untuk menghindari risiko bahwa jika terjadi kerusakan selama proses penulisan, tidak ada versi utuh dari teks yang akan tetap sama sekali. Anda dapat memeriksa dengan "ls -i" (yang menunjukkan nomor inode) apa perilaku editor Anda.
Marc van Leeuwen
1

ini perlu diperbarui, jawaban di atas sekarang hanya sebagian yang benar:

dengan versi bash saat ini, memodifikasi skrip di-disk saat sedang berjalan akan menyebabkan bash "mencoba" memuat perubahan ke dalam memori dan menjalankannya di skrip yang sedang berjalan. jika perubahan Anda datang setelah baris yang sedang dieksekusi, baris baru akan dimuat dan dieksekusi. tapi, ini dugaan oleh bash dan mungkin bisa benar atau salah.

cara yang lebih baik untuk melakukan ini adalah urutan tindakan berikut: 1) memuat skrip ke dalam memori 2) menghapus skrip dari disk 3) menulis skrip baru ke disk dengan menghapus versi disk terlebih dahulu, versi memori kehilangan tautannya ke sana sehingga ketika Anda menyediakan versi baru di langkah 3, tidak ada upaya oleh bash akan dilakukan untuk memuat konten baru ke dalam versi memori.

ivor
sumber
0

@ jobin jawaban umumnya benar, tetapi saya akan menambahkan beberapa jawaban lain yang mungkin to the point tergantung apa yang ingin Anda lakukan.

Jika Anda ingin mengubah skrip, dan ingin tahu bahwa itu aman, maka Anda ingin menulis ke file baru, bukan yang sudah ada, File baru dapat ditemukan di tempat yang lama. Tulis versi baru Anda ke file baru, dan kemudian gunakan mvuntuk memindahkannya ke atas dari yang lama. File yang telah diganti masih ada, hanya saja tidak ditautkan dari direktori. Skrip Anda yang sedang berjalan dapat terus menggunakannya, dan ketika skrip itu menutup file-nya, sistem akan tahu bahwa ia dapat membersihkan file dengan aman (baik segera atau nanti).

Jika Anda ingin berperilaku seperti script saat itu, Anda memiliki masalah yang lebih sulit. Saya harap Anda perlu membuatnya menjadi kode skrip. Skrip Bash dapat menangani sinyal (misalnya dapat menangkap sesuatu sepertikill -USR1 [pid] ), dan skrip kemudian dapat merespons dengan memuat ulang beberapa kode. Jadi mungkin Anda bisa mendapatkan fungsionalitas mendekati apa yang Anda inginkan, tetapi tanpa mengetahui apa yang Anda cari, saya tidak melihat alasan yang baik untuk melakukan ini, dan saya curiga jika Anda ingin melakukan sesuatu yang kompleks ini Anda mungkin ingin yang lebih canggih bahasa pemrograman untuk melakukannya.

Jika Anda ingin meretas perilaku skrip yang berjalan yang tidak ditulis dengan pemikiran ini, maka Anda kurang beruntung. Saya ragu untuk menyebut tugas pemrograman yang tidak mungkin, tetapi jika Anda memiliki sumber daya dan keterampilan untuk tugas semacam ini, Anda mungkin tidak akan bertanya di sini.

mc0e
sumber