Как сделать сценарии оболочки надежными для источника, который изменяется при запуске
Люди заметили, что если вы измените источник оболочки script, все запущенные в данный момент экземпляры будут терпеть неудачу?
Это, на мой взгляд, очень плохо; это означает, что я должен убедиться, что все экземпляры script остановлены до внесения изменений. Мое предпочтение было бы в том, что существующие скрипты продолжают работать со старым исходным кодом, а новые экземпляры используют новый код (например, что происходит для программ perl и python).
Есть ли у людей какие-либо хорошие обходные пути для этого поведения, кроме предварительного копирования оболочки script в tempfile и запуска из этого?
Спасибо,
/YGA
Ответы
Ответ 1
Очень небольшое дополнение к другим ответам ниже:
#!/bin/sh
{
# Your stuff goes here
exit
}
В конце важно exit
. В противном случае в конце файла script все еще можно получить доступ, чтобы увидеть, есть ли еще строки для интерпретации.
Этот вопрос был позже реорганизован здесь: Может ли оболочка script указать, что ее строки сначала загружаются в память?
Ответ 2
Убедитесь, что оболочка должна проанализировать весь файл перед выполнением любого из них:
#!/bin/ksh
{
all the original script here
}
Это трюк.
Кстати, с Perl (и я предполагаю Python) программа анализирует весь файл перед тем, как исполнить его, в точности так, как это рекомендовано здесь. Вот почему вы обычно не сталкиваетесь с проблемой с Perl или Python.
Ответ 3
Желаемое поведение может быть невозможно, в зависимости от сложности сценариев оболочки, которые задействованы.
Если полная оболочка script содержится в файле с одним исходным кодом, и этот файл полностью разбирается перед исполнением, то оболочка script обычно безопасна от изменений в копии на диске во время выполнения. Обертка всех исполняемых операторов в функцию (или ряд функций), как правило, будет достигать поставленной цели.
#!/bin/sh
doit()
{
# Stuff goes here
}
# Main
doit
Трудность возникает, когда оболочка script "включает в себя" другие сценарии оболочки (например, "." или "source" ). Если они включают завернутые в функцию, они не анализируются до тех пор, пока этот оператор не будет достигнут в потоке выполнения. Это делает оболочку script уязвимой для изменений этого внешнего кода.
Кроме того, если оболочка script запускает любую внешнюю программу (например, оболочку script, скомпилированную программу и т.д.), этот результат не фиксируется до тех пор, пока эта точка выполнения не будет достигнута (если вообще).
#!/bin/sh
doit()
{
if [[some_condition]] ; then
resultone=$(external_program)
fi
}
# Main
doit