
У меня есть приложение, которое отлично работает, с '&' и без него, когда запускается напрямую из терминала. Однако, если я пытаюсь выполнить его из скрипта оболочки, оно работает только если пропустить завершающий '&'. Таким образом, я не могу запустить этот процесс в фоновом режиме изнутри скрипта оболочки.
<Path to My application> <options> &
Окно приложения открывается, но дальше ничего не происходит.
(Приложение представляет собой модифицированную (мной) версию qemu 0.13.0. Когда я запускаю образ диска из него в фоновом режиме в скрипте оболочки, я застреваю с черным экраном)
решение1
Нет необходимости переводить приложение в фоновый режим с помощью амперсанда, если у него есть встроенная опция для этого. Так происходит с qemu (если вы его не удалили):
% qemu-kvm --help | grep daemon
-daemonize daemonize QEMU after initializing
решение2
Видите ли вы сообщение типа
[1] suspended (tty output) myapplication
в терминале? Это сообщение означает, что ваша программа пытается прочитать с терминала (вероятно, потому что она читает со своего стандартного ввода). Поскольку только программа переднего плана может читать с терминала, программа приостановлена.
Если вы видите это сообщение, выясните, почему ваша программа читает. В отчаянии попробуйте перенаправить ее стандартный ввод ( myapplication </dev/null
).
Если вы не видите такого сообщения, это какая-то другая ошибка в вашей программе. Посмотрите, что делает ваша программа в отладчике или с помощью strace
.
решение3
Существует разница между запуском фоновой команды из терминала и из скрипта оболочки.
В неинтерактивной оболочке (с отключенным управлением заданиями) стандартный ввод фоновой команды неявно перенаправляется из /dev/null
, что может привести к тому, что ваша команда вообще не будет выполнена.
См. стандарт POSIX наЯзык команд оболочки: асинхронные списки.
# compare where fd 0 is pointing to
sh -c 'sleep 10 & lsof -p ${!}'
sh -c 'sleep 10 0<&0 & lsof -p ${!}'
sh -c 'set -m; sleep 10 & lsof -p ${!}'
sh -ic 'sleep 10 & lsof -p ${!}'