Чи можу я змінити файл bash script (.sh), поки він працює?


28

Припустимо, у мене є сценарій script.sh, який потребує певного часу для виконання. Я виконую його, ./script.sh. Поки він працює у вікні терміналу, я змінюю файл script.sh. Чи це матиме вплив на вже запущений процес?

Після його зміни я виконую модифікований файл, тому зараз у мене є два запущені процеси. Це добре?


Відповіді:


36

Коли ви вносите зміни до свого сценарію, ви вносите зміни на диск (жорсткий диск - постійне сховище); під час виконання сценарію сценарій завантажується у вашу пам'ять (ОЗП).

Отже, зміни, внесені в сценарій, не вплинуть на запущений сценарій, він запустить версію, яку ви виконали перед внесенням цих змін.

Однак, коли ви знову виконаєте змінений скрипт, не припиняючи раніше запущений екземпляр, буде два екземпляри сценарію - один, який має зміни, і старий.

Попереджуйте, що ресурси, які сценарій використовує та модифікує, будуть конфліктувати. Наприклад, якщо ви змінюєте файл за допомогою скрипту, сценарій, який запускається пізніше, не зможе відкрити цей файл для запису і не вдасться виконати правильно.

Оновлення: Дякую Зареєстрованому користувачеві, що вказав на кращу відповідь на Unix.stackexchange.com.

Залежно від розміру сценарію та відповідного компілятора / інтерпретатора, сценарій завантажується частково / повністю. Отже, якщо сценарій не завантажений повністю, зміни, внесені до вашого сценарію, відображатимуться на запущеному екземплярі, як тільки частина сценарію завантажується в пам'ять.

Отже, не рекомендується змінювати свій скрипт на диску, який зараз працює для непередбачуваного виводу: спочатку зупиніть запущений екземпляр, а потім змініть свій сценарій, а потім повторно виконайте сценарій.


11
Не ідеальна відповідь, читайте unix.stackexchange.com/q/121013/55673
Зареєстрований користувач

@registereduser: о так, це питання просто нагадало мені мої уроки з ОС. Я відредагую свою відповідь, як тільки я стану рукою на робочий стіл (зараз на телефоні)
Jobin

Я думаю, що для коротких сценаріїв не повинно виникнути проблем.
бекко

1
Коли я спробував це з bash v3.2.48 (див. Тут ), він не буфер за межі кінця рядка (і погано вийшов з ладу, коли я змінив сценарій під час його виконання). Я щойно перевірив bash v4.3.0, і він створив весь (короткий) сценарій. Отже ... я б не розраховував на якусь особливу поведінку.
Гордон Девіссон

1
@RegisteredUser Не з усіма версіями bash - див. Приклад, який я пов’язав.
Гордон Девіссон

4

Я додам щось, що, на мою думку, не було сказано в інших відповідях. Багато що залежить від того, як ви редагуєте файл. echo "stuff" >fileДумаю, що робити з оболонки (інший екземпляр) дійсно буде перезаписаний файл. Але якщо ви відредагуєте файл, наприклад, emacsа потім збережіть, цього не станеться. Натомість тут редактор перейменовує старий файл на якесь ім’я резервної копії (можливо, фактично видаляючи попередню резервну копію), а потім записує його змінений вміст буфера у новий файл зі старим іменем (тепер оновленим) . Так як оболонка (або інший інтерпретатор) читає сценарій майже напевно відкрити файл лише один раз, то після цього НЕ залежить від місцезнаходження файлу ім'я, він просто продовжує читати файл фізичного диска (ідентифікований за номером inode), який був пов'язаний з ім'ям файлу на момент відкриття. Тож навіть якщо він читає скрипт у блоках (що було б найпростішим рішенням, якщо використовувати буферизований текст I / O), він продовжуватиме читати рядки зі старого примірника файлу, який, ймовірно, не зміниться вашим редагуванням.


+1 Я використовую Sublime Text як свій редактор. Чи знаєте ви, чи він занадто перейменовує файл, наприклад emacs?
беско

1
Я думаю, що більшість редакторів використовує схему перейменування (навіть якщо вони не повинні зберігати резервні версії), щоб уникнути ризику, що якщо в процесі запису відбудеться збій, жодна недоторкана версія тексту не залишиться взагалі. Ви можете перевірити за допомогою "ls -i" (який показує числа inode), якою є поведінка вашого редактора.
Марк ван Левен

1

це потрібно оновити, наведені вище відповіді лише частково правильні:

з поточною версією bash, зміна скрипту на диску під час його запуску призведе до того, що bash "спробує" завантажити зміни в пам'ять і прийняти їх у запущеному сценарії. якщо ваші зміни відбудуться після рядка, що виконується в даний час, нові рядки будуть завантажені та виконані. але, це здогад Баша, і це може бути правильним чи неправильним.

кращий спосіб зробити це наступна послідовність дій: 1) завантаження скрипту в пам'ять 2) видалення сценарію з диска 3) написання нового скрипту на диск, спочатку видалення версії диска, версія пам'яті втрачає свої посилання на нього так що коли ви надаєте нову версію на кроці 3, не буде здійснено спроб bash для завантаження нового вмісту у версію пам'яті.


0

@ відповідь jobin, як правило, правильна, але я додам деякі інші відповіді, які можуть бути до речі, залежно від того, що ви хочете зробити.

Якщо ви хочете змінити скрипт, і хочете знати, що це безпечно, тоді ви хочете написати в новий файл, а не в існуючий. Новий файл може бути розташований там, де був старий. Напишіть нову версію в новий файл, а потім скористайтеся, mvщоб перемістити її на місце вгорі старого. Файл, який було замінено, все ще існує, він просто не пов'язаний із каталогу. Ваш запущений скрипт може продовжувати його використовувати, і коли цей скрипт закриває свою файлову обробку, система знає, що може безпечно очистити файл (негайно чи пізніше).

Якщо ви хочете поводитися з поведінкою сценарію на льоту, у вас є більш складна проблема. Я думаю, вам знадобиться вбудувати його в код сценарію. Сценарії Bash можуть обробляти сигнали (наприклад, можуть вловлювати щось на зразок kill -USR1 [pid]), а потім сценарій може відповісти, перезавантаживши деякий код. Тож, можливо, ви можете отримати функціонал, близький до того, що ви хочете, але не знаючи, що ви хочете, я не бачу вагомих причин для цього, і я підозрюю, що ви хочете зробити щось таке складне, ви, напевно, хочете більш досконалого. мови програмування, щоб зробити це в.

Якщо ви хочете зламати поведінку запущеного сценарію, який не записаний з цим на увазі, то вам не пощастить. Я б вагався називати будь-яке завдання програмування неможливим, але якби у вас були ресурси та навички для такого роду завдань, ви, ймовірно, не запитували б тут.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.