Хорошо обычно устройства массового хранения, такие как карты флэш-памяти USB смонтированы с помощью команды, mount
. Они должны быть явно размонтированы с помощью комплимента для этой команды, umount
(это не опечатка). Существуют инструменты, которые могут обнаружить события на аппаратном уровне, такой как, USB-устройство было просто включено. Эти "сервисы" затем сделают монтирование автоматически для Вас. Это - то, что происходит, когда Вы будете использовать рабочий стол GNOME, и Вы будете обычно видеть, что Карты памяти обнаруживаются, как смонтировано в Наутилусе файлового браузера.
Это немного более хитро для знания, когда устройство больше не пишется в. Необходимо было бы записать собственный обработчик для этого использования Udev и сообщений DBUS для знания, когда устройство было сделано, будучи записанным в каждый раз, и затем сохраните его явно в "размонтированном" состоянии.
Я не вижу никакой другой способ сделать это без большой глубокой интеграции в различные подсистемы в Linux, и к моему знанию, которое просто не существует на данный момент.
Мое предположение было бы то, что на OSX, они работают sync
команды и отъезд "смонтированного" устройства, который можно считать опасной вещью сделать, но в удобстве для оператора.
отредактируйте свой бэш-скрипт, чтобы "поймать в ловушку" выход из Программы-А. затем подскажите, чтобы вмешаться вручную, в этот момент вы должны ответить "y" - это безопасно, чтобы продолжить работу с Программой-В. Один из способов сделать это заключается в том, чтобы обойти Программу-А, перехватить код выхода, если он не является успешным, затем запросить вмешательство пользователя, продолжить цикл до тех пор, пока не будет найден действительный выход. Затем перейдите к Программе-B.[116231].
Итак, ниже вы найдете этот очень длинный и, вероятно, склонный к ошибкам макет того, как, по моему мнению, такая вещь может работать. Он вставляет исполняющую
функцию ab_start между program_a и program_b для обеспечения очистки их соответствующих lock файлов между вызовами любой из функций и перекрывающимся switch. lock разворачивается для каждого вызова ab_start. Итак:
trap
и пока она успешно не снимет switch.lock. Затем он делает все, что угодно, пока не появится program_b.lock, все время передавая свой журнал через sed
. sed
следит за выводом журнала program_a на предмет regex
signal_output, в это время он открывает program_b.lock и записывает в него перехваченную строку.
sed
с удовольствием перекачивает все данные журнала, проходящие через него, в program_a.log, как умный tee
. убивает
себя. /dev/fd/4 <
файл, добавленный к ее входу, и выполняет его. Затем он:
touch
es switch.lock&
выполняет вызов ab_start с инструкциями по запуску program_b while
ждет, пока program_b.lock и switch.lock волшебным образом исчезнут, после чего... touch
es switch.lockexec
прямо в себя. exec
целевой параметр и смещает его, затем
sleep
или rm
, пока оба {a_b}.lock
s не исчезнутtouch
es {a_b}.lock
exec
s в свой целевой ловушку
затем sleep
или rm
, пока switch.lock
не исчезнет. kill
s себя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
я думаю, что здесь хорошая идея.
Может быть, вы можете просто приостановить 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
Одна из самых простых вещей, которые можно сделать в сценарии оболочки, - это последовательный запуск программ. Вы можете сделать что-то вроде этого:
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()
, вероятно, более эффективен и, конечно, менее подвержен ошибкам.