Я предполагаю, что Java не думает, что сценарий закончен, пока каналы, которые он передал ему через stdin / stdout / stderr, не будут закрыты подпроцессом. То есть в stdin больше нет активных процессов чтения, в stdout / stderr больше нет активных процессов записи.
Когда вы читаете по каналу, вы не получите указание конца файла, пока не будет больше нет процессов , у которых канал открыт для вывода. Таким образом, если процесс разветвляется и новый процесс наследует дескриптор открытого файла, то исходный процесс завершается, процесс все еще остается с открытым файлом, и читатель все еще ждет.
Аналогично с записываемой вами трубкой, вы не получите сигнал «сломанная труба», пока последний читатель не закроет канал.
Эта проблема обычно возникает, когда ваш скрипт отключает фоновые задачи (например, недавно установленные службы), которые наследуют stdin / stdout / stderr.
Используя exec, вы явно нарушаете цепочку наследования этих каналов, чтобы фоновые процессы не использовали их.
Если в Linux, проверьте / proc / * / fd на наличие новых сервисов и посмотрите, является ли их stdin / stdout / stderr тем же каналом, который ваш Java-процесс передает вашему сценарию.
Та же самая ситуация часто возникает, когда вы запускаете сценарии /etc/init.d/xxx: они завершаются нормально, когда вы запускаете их из командной строки, но, кажется, зависают, когда вы запускаете их с какого-то монитора.
EDIT:
Вы говорите, что скрипт установщика содержит строку:
exec 3>&1 >>/var/log/another-log.log 2>&1
Первый член, 3> & 1, клонирует стандартный вывод в файл-дескриптор 3 (см. Перенаправления в man bash). Насколько я знаю, fd 3 не имеет особого значения. Затем он заменяет стандартный вывод, открывая /var/log/another-log.log, и заменяет стандартный вывод клонированием стандартного вывода. См. Раздел «Перенаправления» справочной страницы bash
Это означает, что новый дескриптор файла 3 открыт для записи в канал, который изначально был передан как STDOUT. Программы, которые ожидают быть демонами системной службы, часто закрывают файловые дескрипторы 0 (STDIN), 1 (STDOUT) и 2 (STDERR), но могут не беспокоить других. Кроме того, теперь, когда оболочка открыла FD-3, она передаст этот открытый файл любой выполняемой команде, включая фоновые команды.
Знаете ли вы, есть ли какая-то конкретная причина, по которой установщик открывает FD 3? Я предполагаю, что если вы просто удалите термин «3> & 1» из установщика, ваша проблема будет решена. Это позволит вам полностью удалить exec из вашего скрипта