Предположим, у меня есть скрипт script.sh
, выполнение которого занимает некоторое время. Я исполняю это ./script.sh
. Пока он работает в окне терминала, я изменяю файл script.sh
. Повлияет ли это на уже запущенный процесс?
После его изменения я запускаю измененный файл, поэтому у меня сейчас два запущенных процесса. Это нормально?
scripts
filesystem
becko
источник
источник
Ответы:
Когда вы вносите изменения в свой скрипт, вы вносите изменения на диск (жесткий диск - постоянное хранилище); когда вы выполняете скрипт, скрипт загружается в вашу память (RAM).
Таким образом, изменения, которые вы вносите в сценарий, не влияют на выполняемый сценарий, он запускает версию, которую вы выполнили до внесения этих изменений.
Однако при повторном выполнении измененного сценария без прерывания ранее запущенного экземпляра будет два экземпляра сценария: один с изменениями и старый.
Имейте в виду, что ресурсы, которые использует и изменяет скрипт, будут конфликтовать. Например, если вы изменяете файл с помощью сценария, сценарий, который запускается позже, не сможет открыть этот файл для записи и не сможет правильно работать.
Обновление: спасибо зарегистрированному пользователю за указание лучшего ответа на Unix.stackexchange.com.
В зависимости от размера скрипта и рассматриваемого компилятора / интерпретатора, скрипт загружается частично / полностью. Таким образом, если сценарий загружен не полностью, изменения, внесенные в сценарий, будут отражены в работающем экземпляре после загрузки части сценария в память.
Поэтому не рекомендуется менять сценарий на диске, который в данный момент выполняется для непредсказуемого вывода: сначала остановите работающий экземпляр, затем измените сценарий, а затем повторно запустите сценарий.
источник
Я добавлю что-то, что, я думаю, не было сказано в других ответах. Многое зависит только от того, как вы редактируете файл. Думаю, выполнение
echo "stuff" >file
из оболочки (другой экземпляр) действительно перезапишет файл. Но если вы отредактируете файл, например,emacs
а затем сохраните, этого не произойдет. Вместо этого редактор переименовывает старый файл в какое-то имя резервной копии (возможно, фактически удаляя предыдущую резервную копию), а затем записывает измененное содержимое буфера в виде нового файла со старым именем (которое теперь является libreated) . Так как оболочка (или другой интерпретатор) читает сценарий почти наверняка открыть файл только один раз, то после этого не зависит от местонахождения файла имя, он просто продолжает читать файл физического диска (идентифицируемый по номеру инода), который был связан с именем файла во время открытия. Таким образом, даже если он читает скрипт в блоках (что было бы самым простым решением при использовании буферизованного текстового ввода-вывода), он продолжал бы читать строки из старого экземпляра файла, который, вероятно, не изменится при вашем редактировании.источник
emacs
?это необходимо обновить, приведенные выше ответы теперь только частично верны:
в текущей версии bash изменение скрипта на диске во время его работы приведет к тому, что bash попытается загрузить изменения в память и принять их в работающем скрипте. если ваши изменения появятся после текущей выполняемой строки, новые строки будут загружены и выполнены. но это предположение Bash, и оно может сделать это правильно или неправильно.
лучший способ сделать это - выполнить следующую последовательность действий: 1) загрузить сценарий в память 2) удалить сценарий с диска 3) записать новый сценарий на диск, сначала удалив версию диска, версия памяти теряет свои ссылки на него так что, когда вы предоставляете новую версию на шаге 3, не будет предпринята попытка bash загрузить новое содержимое в версию памяти.
источник
Ответ @ jobin, как правило, правильный, но я добавлю некоторые другие ответы, которые могут быть в зависимости от того, что вы хотите сделать.
Если вы хотите изменить сценарий и хотите знать, что он безопасен, то вы хотите записать в новый файл, а не в существующий. Новый файл может быть расположен там, где был старый. Запишите новую версию в новый файл, а затем используйте ее,
mv
чтобы переместить на место поверх старой. Файл, который был заменен, все еще существует, он просто не связан с каталогом. Ваш работающий скрипт может продолжать его использовать, и когда этот скрипт закрывает свой дескриптор файла, система знает, что может безопасно очистить файл (как сразу, так и позже).Если вы хотите вести себя сценарием на лету, у вас есть более сложная проблема. Я ожидаю, что вам нужно встроить его в код скрипта. Сценарии Bash могут обрабатывать сигналы (например, могут отлавливать что-то подобное
kill -USR1 [pid]
), а затем сценарий может ответить путем перезагрузки некоторого кода. Так что, возможно, вы можете получить функциональность, близкую к тому, что вы хотите, но не зная, что вам нужно, я не вижу веской причины для этого, и я подозреваю, что если вы хотите сделать что-то такое сложное, вы, вероятно, хотите более сложный язык программирования, чтобы сделать это в.Если вы хотите взломать поведение запущенного скрипта, который не написан с учетом этого, то вам не повезло. Я бы не решался назвать любую задачу программирования невозможной, но если бы у вас были ресурсы и навыки для такой задачи, вы, вероятно, не стали бы спрашивать здесь.
источник