Выйти из терминала после запуска сценария bash

Я пытаюсь написать скрипт bash для открытия определенных файлов (в основном файлов PDF) с помощью команды gnome-open. Я также хочу, чтобы терминал выходил, когда он открывает файл pdf.

Я попытался добавить exit в конец моего скрипта, однако это не закрывает терминал. Я попытался найти в Интернете ответ на мой вопрос, но я не мог найти подходящего, я был бы очень признателен, если бы вы, ребята, могли помочь.

Мне нужен ответ, который убивает только терминал который я запускаю командой не все терминалы, это было бы возможно? Предыдущий ответ, который я принял, убивает все открытые окна терминала. Я не понимал, что это было до сегодняшнего дня.

1
задан 22 April 2015 в 09:55

6 ответов

Этот скрипт завершает терминал и, следовательно, оболочку и себя.

Он беспощадно убивает все процессы. Если в терминале открыто несколько вкладок, они также закрыты.

Он безжалостно убивает все процессы. Если в терминале открыто несколько вкладок, то они также закрыты.

В этом случае сценарий должен запускаться в независимом терминале, например xterm

[ f1] PPID PPID - это идентификатор родительского процесса, в этом случае PPPID оболочки (e.g. /bin/bash) PPPID - это идентификатор родительского процесса PPID, в этом случае окно терминала <your_command> & disown. В оболочке bash, команда disown builtin используется для удаления заданий из таблицы заданий или для отметки заданий, чтобы сигнал SIGHUP не отправлялся им, если родительская оболочка получает ее (например, если пользователь выходит из системы). awk '{print $4}' "/proc/$PPID/stat" Получает значение четвертого столбца файла /proc/$PPID/stat (например, для /proc/1/stat он возвращает 0)
4
ответ дан 23 May 2018 в 21:12
  • 1
    Я думаю, что команда $$ получит pid терминала ... Это было бы альтернативой? Не могли бы вы также объяснить, как отречься? – Tim 20 April 2015 в 16:59
  • 2
    Как этот скрипт делает это? Я все еще новичок в сценариях оболочки, поэтому я не могу понять эти команды. Не могли бы вы объяснить, как он закрывает терминал – Rumesh 20 April 2015 в 17:10
  • 3
    @Tim Нет, он возвращает оболочку в терминале: ps xa | grep $$ = & gt; [F2] – A.B. 20 April 2015 в 17:39
  • 4
    @RumeshSudhaharan Он убивает все окно терминала, в котором запускается скрипт, но никаких других окон терминала. – A.B. 20 April 2015 в 18:36
  • 5
    @ A.B. вы ранее говорили, что это только убивает текущее окно терминала, а не любое другое. Сегодня я использовал этот скрипт с открытыми двумя терминальными окнами, и оба они были убиты после запуска скрипта. – Rumesh 22 April 2015 в 10:02

Вы можете использовать exec ./your-script.

Терминальный эмулятор, такой как GNOME Terminal, завершает работу, когда внутри него запускается начальный процесс, который обычно является оболочкой.

Если вы уже находитесь в терминале и единственное, что хотите сделать, прежде чем покинуть этот терминал, чтобы запустить конкретный скрипт (или программу), то это означает, что вам больше не нужна оболочка, работающая в ней. Таким образом, вы можете использовать встроенную оболочку exec оболочки, чтобы заставить оболочку заменить себя процессом, созданным вашей командой.

В случае вашего сценария это другой процесс оболочки - так же, как вторая оболочка процесс создается при запуске скрипта без exec.

Синтаксис exec command, например, exec ./your-script.

exec: Пример

Например, предположим, что у меня есть сценарий оболочки, называемый count, отмеченный исполняемый файл и находится в текущем каталоге. Он содержит:

#!/usr/bin/env bash
for i in {5..1}; do echo $i; sleep 1; done

И в терминале я запускаю:

exec ./count

Это печатает цифры 5, 4, 3, 2 и 1, по одному в секунду, а затем закрывается окно терминала.

Если вы запустите это из чего-то другого, кроме первого процесса запустите в своем терминале - например, если вы сначала запустили bash, чтобы запустить другой экземпляр оболочки, то это вернет вас к оболочке, которая создала , заменит сам процесс , а не выйдет из терминала. (Это предостережение применимо в равной степени к методам, основанным на exit.)

Вы можете использовать ./your-script; exit.

Если вы не хотите, чтобы ваша оболочка заменила себя новый процесс (через exec), вы можете сказать, что он придерживается, но выходите сразу после завершения нового процесса.

Для этого запустите команду и команду exit, разделенные [ f20], поэтому они могут быть заданы на одной строке.

Синтаксис command; exit, например ./your-script; exit.

command; exit vs. command && exit

Вы можете заметить, что это похоже на метод ./your-script && exit, предложенный в ответах kos и heemayl. Разница в том, что:

В случае вашего скрипта это другой процесс оболочки - так же, как создается второй процесс оболочки при запуске скрипта без exec. [!d5 ] ; запускает вторую команду независимо от того, сообщала ли первая команда успех.

Какой из них вы хотите, зависит от конкретной ситуации. Если команда не удалась, вы хотите, чтобы вызывающая оболочка (и хостинг-терминал) не вставала? Если это так, используйте &&; Если нет, используйте ;.

Существует также command || exit, который выходит из вызывающей оболочки только в том случае, если command сообщает об ошибке.

2
ответ дан 23 May 2018 в 21:12

Самое простое решение было бы:

xdg-open file.pdf && exit

В отличие от другой подобной команды nohup не требуется, чтобы команда игнорировала SIGHUP, причина, по которой xdg-open, выйдет из нереста дочернего процесса который является предпочтительным приложением для открытия pdf-файла. Поскольку фактический процесс, запущенный с терминала, больше не должен быть убит, nohup не требуется.

&& указывает, что следующая команда будет запущена, если предыдущая команда будет успешной, т.е. вернет выход код 0 ($?=0) и exit просто закроют терминал.

1
ответ дан 23 May 2018 в 21:12
  • 1
    Я думаю, он сказал, что выход не работает ... – Tim 20 April 2015 в 19:09
  • 2
    @Tim: Возможно, OP не использовал его правильно, из вопроса его очень неясно, как он / она положил exit в конце и не работал. – heemayl 20 April 2015 в 19:13
  • 3
    @Tim Потому что OP помещает exit внутри скрипта, что неэффективно, поскольку оно имеет эффект выхода из экземпляра bash, в котором выполняется сценарий, а не родительский экземпляр bash (тот, который связан с терминалом) , что приведет к закрытию терминала – kos 20 April 2015 в 22:54
  • 4
    В любом случае xdg-open работает уже в фоновом режиме и отсоединен от терминала, поэтому вам здесь не нужно nohup, плюс из того, что я понимаю, что OP запускает xdg-open несколько раз внутри скрипта для пакетного открытия нескольких файлов, используя xdg-open, как внутри скрипта, приведет к тому, что сценарий будет завершен с первого xdg-open – kos 20 April 2015 в 23:04
  • 5
    @kos: Нет, я не запускаю xdg-open в backgr, даже если у меня nohup по другой причине & amp; должен быть там. Любой фоновый процесс с исходного терминала будет убит, когда вы убьете родительский терминал .. nohup есть, чтобы его предотвратить .., мне не нужно снова использовать терминал в интерактивном режиме, нет необходимости поставить этот процесс на вторую страницу, что также можно предотвратить, запустив каждый xdg-open && exit в подоболочке .. – heemayl 20 April 2015 в 23:12

Вы можете использовать свой скрипт вместо его запуска, например

$ cat run.sh
exit;
$ ./run.sh #will not close
$ . ./run.sh # will close
1
ответ дан 23 May 2018 в 21:12

Лично я бы выполнил команду, чтобы открыть PDF или другие файлы в подоболочке, поставить задержку, чтобы файлы открылись, а затем выйти. В принципе, вот что я тестировал (nohup gnome-open *.pdf &); sleep 2; exit

Вариация на этом будет nohup gnome-open *.pdf && sleep 2 && exit

0
ответ дан 23 May 2018 в 21:12

Чтобы ответить на вопрос заголовка,

«Закройте терминал после запуска сценария bash»:

Запустите только ваш скрипт в терминале

Не глядя при подробностях, что делает скрипт, скрипт может быть непосредственно запущен внутри терминала с опцией -e (--command), не запуская оболочку - он используется вместо оболочки:

gnome-terminal -e ./script.sh

Используйте опцию -x (--execute), если вы хотите предоставить аргументы сценарию. При этом весь остаток командной строки принимается за команду и аргументы.

gnome-terminal -x ./script.sh foo bar

Если ваш сценарий завершен, нет интерактивной оболочки, которая могла бы задержать все, ожидая ввода пользователя.

Примеры

Тестирование будет завершено только после того, как команда, запущенная в нем, выйдет - например, закрытие после sleep выполняется 4 секунды без оболочки:

gnome-terminal -x sleep 4

Конечно, вы можете использовать скрипты оболочки, потому что ваш скрипт все равно использует другой экземпляр оболочки.

Кроме того, вы можете запустить оболочку с явным скриптом - она ​​не будет интерактивной: [ ! d10]

gnome-terminal -x bash -c "echo 'Hello!'; sleep 4"
0
ответ дан 23 May 2018 в 21:12

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

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