Блокировка запуска терминала

Если вы наберете эту простую тестовую команду:

gnome-terminal -x bash -c "ls;sleep 3"

Вы обнаружите, что она сразу же возвращается (вновь созданный терминал, конечно, задерживается на три секунды). Это противоречит, скажем, rxvt (та же команда, но с e).

Если вы хотите начать блокировку, исторический консенсус, похоже, должен был использовать --disable-factory. К сожалению, это больше не работает (проверено 3.14.2).

Итак, как мне запустить терминал в неасинхронном режиме?

Бонус: konsole, [ f6] и xfce4-terminal, по крайней мере, также имеют одинаковую проблему. Команды для них?

1
задан 23 May 2017 в 15:39

4 ответа

Устроители 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.

3
ответ дан 23 May 2018 в 20:20
  • 1
    +1 для поиска ошибки, предлагая исправление и нажав вверх. К сожалению, мое приложение должно работать с ванильными сборками и быть обратно совместимым (и в любом случае оно не решает проблему для lxterminal и amp; tc., О которой я также неофициально спрашивал). – imallett 22 May 2015 в 22:49

В своей бесконечной мудрости разработчики 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, перед продолжением.
3
ответ дан 23 May 2018 в 20:20
  • 1
    Ваша команда хорошая и короткая, но у нее есть один большой недостаток! Если я закрываю окно дочернего терминала или иным образом завершаю его так, чтобы ваш rm $tmpfile не был достигнут, весь скрипт запускается в бесконечный цикл и его нужно отменить с помощью Ctrl-C. – Byte Commander 22 May 2015 в 21:45
  • 2
    Re: 1, действительно, но мое приложение обеспечивает совместимость, не требуя этого (мое приложение на самом деле также явно поддерживает xterm, rxvt и terminator, среди прочего, уже). Re: 2, +1 это аккуратная идея, и она составляет основу принятого ответа. Хотя проще, я думаю, что ожидание идентификатора процесса является лучшей и безопасной (r) идеей. Благодаря! – imallett 23 May 2015 в 05:35
  • 3
    @imallett да, этот подход может завершиться неудачно, если вы закроете терминал до завершения процесса. Я не понимаю, почему в мире вам нужен терминал в первую очередь? Почему бы просто не запускать команды, которые нужно запускать самостоятельно? Зачем вам нужно открыть 2 отдельных терминала? Я чувствую, что это может быть проблемой XY . – terdon♦ 23 May 2015 в 14:54

Я использую новый gnome-терминал, и поведение, которое вы описали для gnome-terminal, похоже, одинаково для konsole, lxterm и rxvt (все три). Поэтому, поскольку OP пока не ответил на какие-либо комментарии, чтобы уточнить, что он или она хочет, я делаю предположение, что OP хочет продолжать использовать родительский терминал, не дожидаясь завершения дочернего терминала.

Этого можно добиться с помощью gnome-terminal &. Если вы хотите, чтобы дочерний терминал закрывался при выходе из родителя, используйте nohup gnome-terminal &. Чтобы избежать появления ошибок в родительском терминале, используйте gnome-terminal 2> /dev/null & или nohup gnome-terminal 2> /dev/null &.

0
ответ дан 23 May 2018 в 20:20
  • 1
    Спасибо за ответ, но я на самом деле хочу точно наоборот. В моей системе gnome-terminal реализован как скрипт Python, который открывает терминал асинхронно уже. xterm может быть достаточно базовым, чтобы воспроизвести поведение, которое я хочу. – imallett 22 May 2015 в 19:25
  • 2
    Итак, что вы хотите, так это для родительского терминала, прежде чем ждать окончания работы с конечным терминалом? – Sergiy Kolodyazhnyy 22 May 2015 в 19:34
  • 3
    Я бы сказал run (gnome-terminal -x bash -c "ls; sleep 3 & amp; & amp; echo done) или что-то вроде этого – Sergiy Kolodyazhnyy 22 May 2015 в 19:37
  • 4
    Да. К сожалению, эта команда не имеет желаемого эффекта, так как gnome-terminal запускает терминал асинхронно, немедленно возвращается. – imallett 22 May 2015 в 22:23

Для людей в феврале 2017 г. & lt; t & lt; Март 2018 года, который пришел на этот сайт через google, простое решение:

gnome-terminal --disable-factory -e "cmd"

работает и запускает gnome-terminal синхронным / блокирующим образом, как ожидалось.

Проверено в:

Ubuntu 16.04 гном-терминал 3.18.3
0
ответ дан 23 May 2018 в 20:20
  • 1
    3.22.1: Failed to parse arguments: Option "--disable-factory" is no longer supported in this version of gnome-terminal – stevesliva 19 March 2018 в 22:29

Другие вопросы по тегам:

Похожие вопросы: