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

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

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

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

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

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

В данном случае это было бы что-то вроде этого:

gnome-open <path_to_pdf_file> && exit

*<path_to_pfd_file> = путь к файлу pdf

exit помещенный в конец скрипта не работает, потому что он просто завершает работу bash экземпляр, в котором выполняется сценарий, который является другим bash экземпляр, чем внутренний терминал bash пример.

Если вы все равно хотите использовать скрипт, самый простой способ - просто вызвать скрипт следующим образом:

<path_to_script> && exit

Или если скрипт находится в текущем рабочем каталоге терминала, например:

./<script> && exit

Если ты действительно если вы не хотите / не можете этого сделать, второй самый простой способ - добавить эту строку в конец вашего скрипта:

kill -9 $PPID

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

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

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

Проблема заключается в том, что если открыто несколько терминалов, и это дочерние процессы gnome-terminal-server, все терминалы будут уничтожены.

В этом случае скрипт должен быть запущен в независимом терминале, например xterm

<your_command> & disownPPPID=$(awk '{print $4}' "/proc/$PPID/stat")kill $PPPID
  • PPID

    PPID - это идентификатор родительского процесса, в данном случае оболочки (e.g. /bin/bash)

  • PPPID

    PPPID - это идентификатор родительского процесса PPID, в данном случае окна терминала

  • <your_command> & disown

    В оболочке bash встроенная команда disown используется для удаления заданий из таблицы заданий или для пометки заданий, чтобы им не отправлялся сигнал SIGHUP, если родительская оболочка его получит (например, если пользователь выйдет из системы).

  • awk '{print $4}' "/proc/$PPID/stat"

    Возвращает значение четвертого столбца файла /proc/$PPID/stat (например, для /proc/1/stat он возвращает 0)

Вы можете использовать exec ./ваш-сценарий.

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

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

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

Синтаксис таков exec команда, например, exec ./ваш-сценарий.

exec: пример

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

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

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

exec ./count

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

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

Вы можете использовать ./ваш-сценарий; выход.

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

Чтобы сделать это, запустите свою команду и exit команда, разделенная ; таким образом, они могут быть даны в одной строке.

Синтаксис таков команда; выход, например, ./ваш-сценарий; выход.

команда; выход против. команда && выход

Вы можете заметить, что это похоже на ./ваш-сценарий && выход способ, предложенный в кос - это и химайла ответы. Разница в том, что:

  • && запускает вторую команду только в том случае, если первая команда сообщил, что это удалось путем возврата нулевого кода выхода.
  • ; выполняет вторую команду независимо от того, сообщила ли первая команда об успешном выполнении или нет.

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

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

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

$ cat run.shexit;$ ./run.sh #will not close$ . ./run.sh # will close

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

Вариацией на этот счет было бы nohup gnome-open *.pdf && sleep 2 && exit

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

xdg-open file.pdf && exit

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

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

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

"Выход из терминала после запуска скрипта bash";:

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

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

gnome-terminal -e ./script.sh

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

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

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

Примеры

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

gnome-terminal -x sleep 4

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

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

gnome-terminal -x bash -c "echo 'Hello!'; sleep 4"

Вы запускаете скрипт в терминале в первую очередь? Строго из командной строки, для этого нет причин открывать терминал.

Да, я запускаю скрипт из терминала. Я не понимал, что есть разница между терминалом и командной строкой

Я заменил “gnome-open” на “xdg-open” в своем скрипте, но изменений нет. Терминал по-прежнему остается открытым

@Tim Вау, это работает =) +1

@Tim, Но мое решение тоже было неплохим. :wink:

@Tim да, это правда. :\

Используете ли вы скрипт для открытия только одного файла? Или вы используете его для открытия нескольких файлов?

Я открываю только один файл за раз

@RumeshSudhaharan Хорошо, я обновил свой ответ

У меня есть скрипт, который открывает два других окна терминала с добавлением символа &, чтобы они оставались открытыми независимо друг от друга. Однако выход в конце скрипта игнорируется.