Войти в систему

Home
    - Создать дневник
    - Написать в дневник
       - Подробный режим

LJ.Rossia.org
    - Новости сайта
    - Общие настройки
    - Sitemap
    - Оплата
    - ljr-fif

Редактировать...
    - Настройки
    - Список друзей
    - Дневник
    - Картинки
    - Пароль
    - Вид дневника

Сообщества

Настроить S2

Помощь
    - Забыли пароль?
    - FAQ
    - Тех. поддержка



Пишет Русскоязычное Linux-сообщество ([info]lj_ru_linux)
@ 2013-07-16 15:42:00


Previous Entry  Add to memories!  Tell a Friend!  Next Entry
bash-скриптинг и все-все-все [Решено]
Приветствую. У меня есть вот какой расклад: есть машина с zLinux (SLES) 11.3. На ней есть пользователь, у которого в качестве командной строки прописан /bin/bash. На машине есть скрипт-менюшка (первая строка - #!/bin/sh), который по нажатию клавиши запускает другой скрипт, который запускает java [parameters] &.

Случай А. Запуск скрипта-менюшки прописан пользователю в .profile, а после него в .profile стоит exit. Пользователь может запустить java, но, когда он выходит из системы (не скрипта, а именно системы, я проверял), ява завершается.

Случай В. Запуск скрипта-менюшки из .profile вынесен, и он запускается из командной строки. При этом, если пользователь запускает java из менюшки, а потом выходит из системы, ява остается работать.

WTF? Иерархия процессов в обоих случаях одинаковая: sshd -> -bash -> /bin/sh menu.sh. Запущенная java одинаково считает родительским процессом 1. Словом, мне совершенно непонятны причины различия.

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

UPD: пришел ответ от поддержки.

1. Замечание случаю А (первое предложение)
------------------------------------------------------
Если в ходе выполнения .profile сессионный bash встречает exit (в самом профайле, а не где-нибудь во внутреннем скрипте), то он завершается, и сессия полноценно так и не запустится.
Это легко проверить, поместив exit , например, в конце файла .profile .

2. Запущенные из .profile и из сессии фоновые процессы, имеющие одинаковые PPID ( 1 ) , при этом обычно имеют разные идентификаторы групп процессов PGID .
Интерпретатор bash , запускаемый при открытии сессии (сеанса), становится лидером сессии (сеанса), и получает идентификатор сессии ( SID ) и PGID равными своему PID .
Фоновый процесс, запускаемый из профайла, получает PGID и SID, равные SID лидера сессии. Фоновый же процесс, запускаемый из сессии, получает PGID, отличный от SID ( обычно равный своему PID или PID процесса, запустившего фоновый).
При завершении сеанса лидер сессии ( bash ) сигналом SIGHUP завершает те фоновые процессы, у которых PGID и SID равны его SID, даже если у них нет управляющего терминала.
Если же PGID отличен от SID, то этот фоновый процесс отсоединяется от управляющего терминала, если таковой имеется, и живёт дальше.

3. Есть несколько способов не допустить завершения фонового процесса, запущенного из профайла.
Можно использовать упомянутую Вами команду nohup, однако она игнорирует стандартный ввод, а стандартный вывод направляет в файл nohup.out .
Также можно с помощью встроенной команды trap замаскировать сигнал SIGHUP, поместив в профайл строку:
trap '' 1
Однако в этом случае сигнал SIGHUP будет замаскирован для всех процессов сессии.
Для решения данной проблемы лучше всего подходит механизм создания новой сессии ( setsid ) .
Если программа доступна в исходных кодах, то следует использовать системный вызов setsid(), в результате выполнения которого PGID и SID вызывающего процесса устанавливаются равными идентификатору вызывающего процесса (PID). Вызывающий процесс будет единственным в этой новой группе процессов и новой сессии.
В случае уже готовой программы нужно воспользоваться командой setsid. Запускаемая с ее помощью программа становится лидером новой сессии, лидером новой группы процессов и не имеет управляющего терминала.


(Читать комментарии) (Добавить комментарий)