Экземпляр замены процесса на месте?

Хорошо обычно устройства массового хранения, такие как карты флэш-памяти USB смонтированы с помощью команды, mount. Они должны быть явно размонтированы с помощью комплимента для этой команды, umount (это не опечатка). Существуют инструменты, которые могут обнаружить события на аппаратном уровне, такой как, USB-устройство было просто включено. Эти "сервисы" затем сделают монтирование автоматически для Вас. Это - то, что происходит, когда Вы будете использовать рабочий стол GNOME, и Вы будете обычно видеть, что Карты памяти обнаруживаются, как смонтировано в Наутилусе файлового браузера.

Это немного более хитро для знания, когда устройство больше не пишется в. Необходимо было бы записать собственный обработчик для этого использования Udev и сообщений DBUS для знания, когда устройство было сделано, будучи записанным в каждый раз, и затем сохраните его явно в "размонтированном" состоянии.

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

MAC OSX

Мое предположение было бы то, что на OSX, они работают sync команды и отъезд "смонтированного" устройства, который можно считать опасной вещью сделать, но в удобстве для оператора.

3
02.03.2014, 15:42
5 ответов
[116260] Мне кажется, что вы пытаетесь заменить процесс RUNNING из OUTSIDE. Это радикальная вещь.

Когда я впервые посмотрел на вопрос, мне показалось, что Вы ищете именно [116714]exec[116715]. Но [116716]exec[116717] вызывается самой программой. Так что если вы не закодировали процесс так, что вы можете заставить его просто выполнять другой процесс, вы не можете делать это во время его выполнения.

Вы можете потенциально создать сигнальную ловушку в вашей Программе-А для [116718]exec[116719] программы с предопределённым именем (которое вы можете затем установить как любое другое), а затем использовать [116720]kill[116721] для этого процесса, чтобы заставить его выполнить [116722]exec[116723]. Внешне это будет выглядеть так, как будто процесс продолжает выполняться - это так, он просто становится кем-то другим. Однако, если вы этого не сделали и хотите сделать это в работающем процессе, я не думаю, что вы можете что-то сделать.

Однако, если внешняя оболочка работает, но еще не запустила критический процесс, вы можете просто заменить файл проблемного процесса.[116267].

2
27.01.2020, 21:11
[116228] Единственный способ сделать это - послать сигнал STOP на Программу-А, а затем использовать gdb (отладчик Gnu) для замены приостановленного кода на код из Программы-А1. Сложность этого, скорее всего, выходит за рамки того, что вы готовы инвестировать (см. [116676]http://mohit.io/blog/debugging-modifying-code-at-runtime/[116677]), поэтому я предлагаю альтернативу:

отредактируйте свой бэш-скрипт, чтобы "поймать в ловушку" выход из Программы-А. затем подскажите, чтобы вмешаться вручную, в этот момент вы должны ответить "y" - это безопасно, чтобы продолжить работу с Программой-В. Один из способов сделать это заключается в том, чтобы обойти Программу-А, перехватить код выхода, если он не является успешным, затем запросить вмешательство пользователя, продолжить цикл до тех пор, пока не будет найден действительный выход. Затем перейдите к Программе-B.[116231].

2
27.01.2020, 21:11

Итак, ниже вы найдете этот очень длинный и, вероятно, склонный к ошибкам макет того, как, по моему мнению, такая вещь может работать. Он вставляет исполняющуюфункцию ab_start между program_a и program_b для обеспечения очистки их соответствующих lock файлов между вызовами любой из функций и перекрывающимся switch. lock разворачивается для каждого вызова ab_start. Итак:

  • program_a не начнет работу, пока не будет установлена trap и пока она успешно не снимет switch.lock. Затем он делает все, что угодно, пока не появится program_b.lock, все время передавая свой журнал через sed.
  • sed следит за выводом журнала program_a на предмет regex signal_output, в это время он открывает program_b.lock и записывает в него перехваченную строку.
    • Тем временем sed с удовольствием перекачивает все данные журнала, проходящие через него, в program_a.log, как умный tee.
  • программа_a завершает свой последний цикл и трагически убивает себя.
  • но программа_a уже поймала сигнал USR1, поэтому она открывает ранее не оцененный /dev/fd/4 < файл, добавленный к ее входу, и выполняет его. Затем он:
    • touches switch.lock
    • & выполняет вызов ab_start с инструкциями по запуску program_b
    • while ждет, пока program_b.lock и switch.lock волшебным образом исчезнут, после чего...
    • touches switch.lock
    • вызывает ab_start с инструкциями exec прямо в себя.
  • тем временем...
  • ab_start сохраняет свой exec целевой параметр и смещает его, затем
    • отказывается делать что-либо, кроме sleep или rm, пока оба {a_b}.locks не исчезнут
    • разочарованно touches {a_b}.lock
    • execs в свой целевой
  • last...
    • program_b устанавливает себе ловушку затем
    • отказывается делать что-либо, кроме sleep или rm, пока switch.lock не исчезнет.
    • делает все, что делает, сколько потребуется времени, и когда через
    • kills себя
    • но находит временную передышку в собственном DIE приложенном here-документе
    • пока успешно не снимет program_b. блокировку
    • и тогда она действительно умирает
  • НО
  • программа_a затем просыпается и выполняетс себя, как объяснено выше.

    HASHBANG

    ab_start() { a_b="$1" ; shift
     while [ -e /locks/program_a.lock ] ||\
     [ -e /locks/program_b.lock ] ; do {
     rm /locks/program_[ab].lock
     sleep 1
     } ; done
     touch /locks/"${a_b}.lock"
     exec "$0" "${a_b}" "$@"
    } 
    
    program_a() { trap '. /dev/fd/4' USR1 ; 
     while [ -e /locks/switch.lock ] ; do {
     rm /locks/switch.lock ; sleep 1
     } ; done
     while [ -e /locks/program_b.lock ] ; do {
     stuff...
     это...
     делает...
     } ; done |\
     sed 's/signal_output/w /locks/program_b.lock'\
     >> /logs/program_a.log
     kill -USR1 $$
    } 4<<-\SUSPEND
     touch /locks/switch.lock
     ab_start program_b "$@" &
     while [ -e /locks/switch.lock ] ||\
     [ -e /locks/program_b.lock ] ; do
     спать 10 
     сделано
     touch /locks/switch.lock 
     ab_start program_a "$@"
    # END
     ОТЛОЖИТЬ
    
    program_b() { trap '. /dev/fd/5' INT QUIT TERM EXIT
     while [ -e /locks/switch.lock ] ; do {
     rm /locks/switch.lock ; sleep 1
     } ; done
     while $work ; do { 
     stuff ...
     это ...
     делает ...
     } ; done
    } 5<<-\DIE
     while [ -e /locks/program_b.lock ] ; do {
     rm /locks/program_b.lock ; sleep 1
     } ; done
    exec 5<&0 <&-
    # СЕЙЧАС
     DIE 
    

    "$@"

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

Определенно, по крайней мере sed я думаю, что здесь хорошая идея.

0
27.01.2020, 21:11

Может быть, вы можете просто приостановить Program-A и запустить Program-A1, а когда Program-A1 завершится, убить Program-A и возобновить ее (в этот момент она обработает SIGTERM, умрет, и ваш скрипт продолжит Program-B):

killall -s STOP Program-A
Program-A1
killall Program-A
killall -s CONT Program-A

Если вы хотите, чтобы Program-A1 унаследовала среду от Program-A , и если в Linux (и предполагая, что все строки среды ] Программа-A содержит как минимум символ = , как обычно), вы можете сделать:

xargs -0 --arg-file="/proc/$(pidof Program-A
  )/environ" sh -c 'exec env -i "$@" Program-A1' sh >> file.log
2
27.01.2020, 21:11

Одна из самых простых вещей, которые можно сделать в сценарии оболочки, - это последовательный запуск программ. Вы можете сделать что-то вроде этого:

if Program-A
then
    Program-B
else
    # handle problems
    if Program-A
    then
        Program-B
    else
        # Program-A failed twice in a row, get help.
    fi
fi

Такая конструкция предотвратит преждевременный запуск программы-B.

Если вы сможете изменить исходный код программы-A, то сможете воспользоваться системным вызовом execve(), который заставляет ядро наложить на программу, вызывающую execve(), код и данные из другого исполняемого файла. Многие вещи переносятся через вызов execve(), например, дескрипторы открытых файлов, идентификатор процесса, но некоторые вещи не переносятся. Вам придется почитать, чтобы понять, какие изменения нужно сделать.

Если я читаю между строк то, что вы пишете, вы можете захотеть сделать комбинацию системных вызовов fork/other work/exec: fork() даст вам два процесса, один из которых может запустить программу-B, а другой перейдет к execve() программы-A1. Или что-то в этом роде. Вам следует уточнить, чего вы хотите.

Далее в левом поле, можно сделать "userland exec". Если все, что вы хотите сделать, это "поменять" одну программу на другую, вы можете сделать это без системного вызова execve(), хотя execve(), вероятно, более эффективен и, конечно, менее подвержен ошибкам.

2
27.01.2020, 21:11

Теги

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