Сценарий оболочки может указать, что его строки загружаются в память первоначально?

ОБНОВЛЕНИЕ: это - пересообщение того, Как сделать сценарии оболочки устойчивыми к источнику изменяемый, когда они работают

Это - немного вещи, которая беспокоит меня время от времени:

  1. Я пишу сценарий оболочки (удар) для быстрого и грязного задания
  2. Я запускаю скрипт, и он работает долгое время
  3. В то время как это работает, я редактирую несколько строк в сценарии, настраивая его для другого задания
  4. Но первый процесс все еще читает тот же файл сценария и получает все завинченные.

По-видимому, сценарий интерпретируется путем загрузки каждой строки из файла, поскольку это необходимо. Есть ли некоторый способ, которым у меня может быть сценарий, указывают к оболочке, что весь файл сценария должен быть считан в память внезапно? Например, сценарии Perl, кажется, делают это: редактирование файла кода не влияет на процесс, это в настоящее время интерпретирует его (потому что это первоначально анализируется/компилируется?).

Я понимаю, что существует много способов, которыми я мог обойти эту проблему. Например, я мог попробовать что-то как:

cat script.sh | sh

или

sh -c "`cat script.sh`"

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

Таким образом, я надеялся на простое решение, которое включит модификации только к сценарию, не пути, которым это вызывается. Я могу просто добавить строку или два в начале сценария? Я не знаю, существует ли такое решение, но я предполагаю, что оно могло бы использовать переменную за 0$...

10
задан Community 23 May 2017 в 12:22
поделиться

6 ответов

Лучший ответ, который я нашел, - это очень небольшая вариация решения, предложенного в Как сделать сценарии оболочки устойчивыми к изменению исходного кода в процессе их выполнения. Спасибо camh за заметку о перепосте!

#!/bin/sh
{
    # Your stuff goes here
    exit
}

Это гарантирует, что весь ваш код будет разобран изначально; обратите внимание, что 'exit' критически важен для обеспечения того, чтобы файл не был доступен позже, чтобы посмотреть, есть ли дополнительные строки для интерпретации. Также, как отмечено в предыдущем сообщении, это не является гарантией того, что другие скрипты, вызываемые вашим скриптом, будут в безопасности.

Спасибо всем за помощь!

9
ответ дан 3 December 2019 в 23:12
поделиться

Если вы используете Emacs, попробуйте M-x customize-variable break-hardlink-on-save . Установка этой переменной скажет Emacs записать во временный файл и затем переименовать временный файл поверх оригинала вместо непосредственного редактирования исходного файла. Это должно позволить работающему экземпляру сохранить свою неизмененную версию, пока вы сохраняете новую версию.

Предположительно, у других полуинтеллектуальных редакторов были бы аналогичные возможности.

0
ответ дан 3 December 2019 в 23:12
поделиться

Подумайте о том, чтобы создать новую дорогу для вашей быстрой и грязной работы. Если вы начинаете свои скрипты с: #! / Usr / local / fastbash

или что-то в этом роде, то вы можете написать оболочку fastbash, которая использует один из упомянутых вами методов. Для переносимости можно просто создать символическую ссылку с fastbash на bash или оставить комментарий в скрипте, в котором говорится, что можно заменить fastbash на bash.

0
ответ дан 3 December 2019 в 23:12
поделиться

Как насчет решения того, как вы его редактируете.

Если сценарий запущен, перед его редактированием сделайте следующее:

mv script script-old
cp script-old script
rm script-old

Поскольку оболочка сохраняет файл открытым до тех пор, пока вы не изменяете содержимое открытого индексного дескриптора, все будет работать нормально.

Вышеупомянутое работает, потому что mv сохранит старый индексный дескриптор, а cp создаст новый. Поскольку содержимое файла не будет фактически удалено при его открытии, вы можете удалить его сразу, и он будет очищен, как только оболочка закроет файл.

2
ответ дан 3 December 2019 в 23:12
поделиться

Используйте редактор, который не изменяет существующий файл, а создает новый файл, а затем заменяет старый. Например, используя :set writebackup backupcopy=no в Vim.

2
ответ дан 3 December 2019 в 23:12
поделиться

Согласно документации bash, если вместо

#!/bin/bash
body of script

вы попробуете

#!/bin/bash
script=$(cat <<'SETVAR'
body of script
SETVAR)
eval "$script"

то, я думаю, вы будете в деле.

1
ответ дан 3 December 2019 в 23:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: