Если вы наберете эту простую тестовую команду:
gnome-terminal -x bash -c "ls;sleep 3"
Вы обнаружите, что она сразу же возвращается (вновь созданный терминал, конечно, задерживается на три секунды). Это противоречит, скажем, rxvt (та же команда, но с e).
Если вы хотите начать блокировку, исторический консенсус, похоже, должен был использовать --disable-factory. К сожалению, это больше не работает (проверено 3.14.2).
Итак, как мне запустить терминал в неасинхронном режиме?
Бонус: konsole, [ f6] и xfce4-terminal, по крайней мере, также имеют одинаковую проблему. Команды для них?
Устроители Ubuntu пакета gnome-terminal заметили эту проблему и создали сценарий оболочки (в пакете Ubuntu gnome-terminal-3.14.2-0ubuntu3) для повторного включения опции --disable-factory; однако, сценарий оболочки не работает!
Из журнала изменений http://changelogs.ubuntu.com/changelogs/pool/main/g/gnome-terminal/gnome-terminal_3.14.2-0ubuntu3/ changelog:
gnome-terminal (3.14.2-0ubuntu3) яркий; urgency = medium debian / gnome-terminal: добавьте скрипт-оболочку для запуска gnome-терминала с другим идентификатором приложения, когда пользователь передает параметр, проигнорированный в настоящее время --disable-factory. Это должно восстановить совместимость со старыми пусковыми установками для пользователей, которые обновляют. [...]Я не могу перемещаться по «Launchpad» Ubuntu (так много для open source), но сценарий оболочки можно найти в http://changelogs.ubuntu.com/
Ошибка в том, что скрипт gnome-terminal.wrap ждет, когда он будет ждать gnome-terminal.wrap.
Ошибка в том, что скрипт gnome-terminal.wrap о неправильном дочернем процессе; он должен ждать на терминальном сервере, а не на терминальном клиенте. Исправление состоит в том, чтобы изменить два метода server_appeared и spawn_terminal_server следующим образом:
def server_appeared(self, con, name, owner):
# start gnome-terminal now
gt = Gio.Subprocess.new(['/usr/bin/gnome-terminal.real',
'--app-id', name] +
self.args,
Gio.SubprocessFlags.NONE)
# removed a line here: gt.wait_async(...)
def spawn_terminal_server(self, name):
ts = Gio.Subprocess.new(['/usr/lib/gnome-terminal/gnome-terminal-server',
'--app-id',
name],
Gio.SubprocessFlags.NONE)
ts.wait_async(None, self.exit_loop, ts)
Вы можете скачать фиксированный файл с: https://gist.github.com/ecatmur/00893506a23e828c6688.
Я уведомил сопровождающего пакета, поэтому, надеюсь, он должен быть исправлен довольно скоро.
Еще один интересный факт: gnome-terminal может быть построен с альтернативой клиент под названием gterminal, у которого есть опция --wait, которая, похоже, делает именно то, что вы хотите. Однако, к сожалению, Ubuntu не создает и не устанавливает его в своем пакете gnome-terminal.
В своей бесконечной мудрости разработчики GNOME решили удалить эту опцию. К сожалению, их мудрость не распространялась и на обновление страницы man, которая все еще перечисляет ее. Таким образом, похоже, что gnome-terminal всегда будет запущен в фоновом режиме, и сеанс родительской оболочки будет немедленно возвращен. Чтобы обойти это, у вас есть несколько вариантов:
Просто используйте другой терминал. Я пробовал с терминаторами xterm, rxvt и GNOME, все из которых работали, как ожидалось. Используйте некоторые уродливые хаки. gnome-terminal при первом запуске запускает /usr/lib/gnome-terminal/gnome-terminal-server. По какой-то причине это означает, что процесс завершается сразу же после его запуска. Чтобы проиллюстрировать:$ gnome-terminal -x sh -c "ls;sleep 30"
[1] 5896
$ jobs
[1]+ Done gnome-terminal -x sh -c "ls;sleep 30"
Как вы можете видеть выше, после запуска в фоновом режиме запущенная работа завершается немедленно. Это означает, что моя первая мысль запустить его в фоновом режиме, а затем использовать $!, чтобы проверить, все ли работает, не будет работать. Это означает, что вам нужно сделать что-то менее элегантное, например, создание файла: tmpfile=$(mktemp); gnome-terminal -x sh -c "ls;sleep 30; rm $tmpfile"
while [ -e $tmpfile ] ; do :; done
Приведенные выше команды будут: i) создавать временный файл (tmpfile=$(mktemp)); ii) запустите gnome-terminal, сообщив ему, чтобы удалить $tmpfile после завершения и iii) ничего не делать (:), пока существует файл temp while [ -e $tmpfile ]. Это приведет к тому, что терминал будет ждать завершения процесса, выполняемого gnome-terminal, перед продолжением. Я использую новый gnome-терминал, и поведение, которое вы описали для gnome-terminal, похоже, одинаково для konsole, lxterm и rxvt (все три). Поэтому, поскольку OP пока не ответил на какие-либо комментарии, чтобы уточнить, что он или она хочет, я делаю предположение, что OP хочет продолжать использовать родительский терминал, не дожидаясь завершения дочернего терминала.
Этого можно добиться с помощью gnome-terminal &. Если вы хотите, чтобы дочерний терминал закрывался при выходе из родителя, используйте nohup gnome-terminal &. Чтобы избежать появления ошибок в родительском терминале, используйте gnome-terminal 2> /dev/null & или nohup gnome-terminal 2> /dev/null &.
Для людей в феврале 2017 г. & lt; t & lt; Март 2018 года, который пришел на этот сайт через google, простое решение:
gnome-terminal --disable-factory -e "cmd"
работает и запускает gnome-terminal синхронным / блокирующим образом, как ожидалось.
Проверено в:
Ubuntu 16.04 гном-терминал 3.18.3