Linux не закрывать терминал после выполнения скрипта

Обновлено: 05.07.2024

Я создал bash script, который открывает несколько гномов-терминалов, подключается к компьютерам класса через ssh и запускает script.

Как я могу избежать закрытия терминала gnome после завершения script? Обратите внимание, что я также хочу иметь возможность вводить дополнительные команды в терминал.

Вот пример моего кода:

Как я понимаю, вы хотите открыть gnome-terminal, выполнить некоторые команды и затем перейти к приглашению, чтобы вы могли ввести еще несколько команд. Gnome-терминал не предназначен для этого варианта использования, но есть обходные пути:

Пусть gnome-terminal запустит bash и сообщит bash для запуска ваших команд, а затем запустите bash

exec bash в конце необходимо, потому что bash -c завершается после выполнения команд. exec заставляет выполняемый процесс заменяться новым процессом, иначе у вас будет два процесса bash.

Пусть gnome-terminal запускает bash с подготовленным rcfile , который запускает ваши команды

Пусть gnome-terminal запускает script, который запускает ваши команды, а затем падает до bash

Установите этот файл как исполняемый файл.

В качестве альтернативы вы можете сделать genericscripttobash :

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

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

Суперпользователь: Создайте профиль, в котором предпочтение "Заголовок и команда/Когда команда выходит" установлена ​​на "Удерживать терминал открытым". Вызовите gnome-terminal с опцией --window-with-profile или --tab-with-profile , чтобы указать имя терминала.

Наконец, это работает для меня:

Запустите с помощью -ic вместо -i , чтобы закрыть терминал bash proccess при закрытии терминала gui:

Идеальное решение - запросить ввод пользователя с эхом " Нажмите любую клавишу".

Но если дважды щелкните в Nautis или Nemo и выберите "запустить" в терминале, он, похоже, не работает.

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

Если описать работу SSH (Secure Shell — безопасная оболочка) простыми словами, то её функция в том, что это простой способ подключиться к удалённому компьютеру от имени существующего на той системе пользователя с возможностью выполнять команды на ней. В первую очередь это относится к командам с интерфейсом командной строки, но также возможна передача и других видов трафика. В более технических терминах, когда мы подключаемся по ssh к другому пользователю на какой-либо системе и запускаем на той машине команды, то в действительности создаётся псевдо терминал и он подсоединяется к оболочке с входом (login shell) выполнившего вход пользователя.

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

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

Основы о процессах в Linux

Нормальные процессы

Нормальные процессы это те, у которых продолжительность жизни ограничивается сеансом. Они запускаются во время сессии как процессы переднего плана и завершаются через определённое время или когда сессия прекращается из-за выхода пользователя. Эти процессы имеют своего владельца, которым является любой валидный пользователь системы, включая root.

Осиротевшие процессы

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

Процессы демонов

Это процессы, которые намеренно сделаны осиротевшими. Процессы, которые намеренно оставлены работающими в системе, называются демонами или намеренно осиротевшими процессами. Обычно это процессы с длительным выполнением, которые после инициации были отсоединены от контролирующего терминала чтобы они могли работать в фоне, пока они не завершать их задачи или пока в них не возникнет ошибка. Родители таких процессов намеренно завершают свою работу, делая так, что дочерний процесс выполняется в фоне.

Техники для сохранения запущенной SSH сессии после отключения

Могут быть различные способы оставить ssh сессию запущенной после отключения, они описаны далее:

1. Использование команды screen для сохранения запущенных сессий SSH

screen — это текстовый менеджер окон для Linux, который позволяет пользователям управлять несколькими сессиями терминала одновременно, переключаться между сессиями, вести журнал действий в сессии для запущенных в screen сессий и даже возобновлять сессии в любой время по нашему желанию не беспокоясь о том, что произойдёт выход из сессии или терминал будет закрыт.

Сессии screen могут быть запущены и затем отсоединены от контролирующего терминала, что оставит их запущенными в фоне и затем их можно заново подсоединить в любое время и даже в любом месте (выполнив вход по SSH с другого компьютера). Всё что нужно, это запустить сессию в screen и когда вы хотите, отсоединить её от псевдо терминала (или контрольного терминала) и выйти из сессии. Когда нужно, вновь выполните вход по SSH и возобновите сессию.

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

Теперь, когда сессия session запущена, можно запустить любую команду и сохранить сессию на случай отключения выполнив отсоединение сессии.

Отсоединение экрана screen

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



Возобновление отсоединённой сессии screen

Если вы хотите возобновить отсоединённую сессию screen, которую вы оставили перед тем как отключиться, просто снова повторно залогинтесь на удалённом терминале и наберите


Предыдущая команда подходит если у вас только одна сессия screen.

Если открыто несколько сессий screen, то после опции -r нужно указать её индивидуальный идентификатор.

Следующая команда при нескольких запущенных сессиях выведет их список с идентификаторами:

Для подключения к одной из них нужно ввести команду вида:

2. Использование Tmux (мультиплексора терминалов) чтобы программа работала после отключения от SSH

Tmux — это ещё одна программ, которая создана на замену screen. В ней имеется большинство возможностей screen, а также несколько дополнительных функций, которые делают её более мощной чем screen.

Она позволяет, кроме всех других опций, которые предлагает screen, разделение экрана терминала по горизонтали и вертикали, чтобы иметь сразу несколько консолей, позволяет изменять размер этих панелей, имеется мониторинг активности сессий, поддержка скриптов используя режим командной строки и т. д. Благодаря этим функциям tmux, он имеется практически во всех дистрибутивах Unix и даже был включён в базовую систему OpenBSD.

Запуск сессии Tmux

После подключения к удалённому хосту по SSH, наберите в командной строке:

Вы откроете новую сессию с новым окном — здесь вы можете делать всё что угодно как в обычном терминале.

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

Отсоединение сессии Tmux от терминала

В запущенной сессии tmux вы можете набрать:



Либо вы можете использовать сочетание клавиш, нажмите Ctrl+b, а затем нажмите d. После этого ваша текущая сессия будет отсоединена и вы вернётесь в ваш терминал, который вы можете безопасно закрыть (отключиться от SSH).

Возобновление фоновой сессии Tmux

Чтобы повторно открыть сессию, которую вы отсоединили и вернуть всё в то состояние, в котором находился терминал до того, как вы отключились от системы, просто повторно залогинтесь на удалённую машину и наберите


чтобы подсоединить закрытую сессию. Она вернётся, и запущенная в ней программа будет работать как прежде.

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

3. Использование команды nohup чтобы программа не закрывалась после отключения от SSH

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

Выполнение команды в фоне используя nohup

Это простой сценарий в котором во время сессии SSH мы запустили команду find для поиска файлов в фоне используя nohup. При отправке работы в фон в приглашение терминала возвращается JOBID и PID процесса.


Возобновление сессии для просмотра всё ещё работающей задачи

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

%JOBID — это цифра в квадратных скобках, например [1], тогда для перевода её на передней план введите:

Если программа уже завершила свою работу, то вы увидите что-то вроде:

По умолчанию программа также сохраняет свой вывод в файл nohup.out — в противном случае, после завершения программы уже не получится вернуть данные, которые вывела программа.

При переводе на передний план программа не показывает свой вывод — в этом состоянии её можно только остановить комбинацией CTRL+c.

4.Использование команды disown для сохранения запущенной сессии SSH

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

Disown удаляет работу из списка процессов работ системы, таким образом, процесс защищён от уничтожения во время отключения сеанса, поскольку он не получит SIGHUP от оболочки при выходе из системы.

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

Выполнение команды с использованием disown в фоновом режиме

Ниже мы отправили команду ping в фоновый режим, чтобы она продолжала работать и была удалена из списка заданий. Как видно, задание было сначала приостановлено, после чего оно все ещё оставалось в списке заданий с идентификатором процесса: 4910.


После этого работе был передан сигнал disown и она была удалена из списка работ, хотя ещё и запущена в фоне. Работа должна ещё быть запущена, когда вы повторно зайдёте на удалённый сервер:


5. Использование команды setsid для поддержания сессии SSH в запущенном состоянии

Другой утилитой для достижения требуемого поведения является setsid. Nohup имеет недостаток в том смысле, что группа процессов процесса остаётся неизменной, поэтому процесс, запущенный с помощью nohup, уязвим для любого сигнала, отправляемого всей группе процессов (например, Ctrl+C).

С другой стороны, setsid распределяет новую группу процессов для выполняемого процесса, и, следовательно, созданный процесс полностью находится во вновь выделенной группе процессов и может безопасно выполняться, не опасаясь быть уничтоженным даже после выхода из сеанса.

Выполните любую команду, используя setsid


Теперь, когда вы повторно войдете в сеанс, вы все равно обнаружите, что этот процесс запущен.

Заключение

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

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

У меня, похоже, были ошибки с Empathy, которые отказывались подключаться к сети в разное время.

Но это займет код, и если вы этого захотите, необходимо сделать отчет об ошибке.

Положите $SHELL в конец вашего скрипта:

alt text

Небольшой недостаток: так как gnome-терминал не запускает bash как оболочку, он будет рассматривать его как приложение и отобразит предупреждение об этом, когда вы попытаетесь закрыть терминал:

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

Этого не произойдет, если вместо gnome-терминала использовать xterm ; если это вас беспокоит.

Using Gnome Terminal

Using gnome-terminal appending ;bash at the end of the command string and calling the script with -c options works. Например:

Так происходит следующее:

  1. открывает gnome-терминал
  2. выполняет скрипт script.sh
  3. показывает bash-сказку после завершения скрипта.

Вы можете выйти из окна gnome-терминала, закрыв окно, или набрав выход в bash-сказке. Или вы можете ввести больше команд по запросу.

Если вы используете xterm , используйте -hold .

Если у вас есть доступ к скрипту, то в конце можно добавить следующий код:

Этот код будет ждать ввода перед закрытием, поэтому терминал будет оставаться открытым до тех пор, пока вы не нажмете Enter.

Использование xterm и добавление ;bash в конце командной строки работает. Например:

Это делает следующее:

  1. открывает xterm
  2. выполняет скрипт script.sh
  3. показывает bash prompt после завершения скрипта.

Вы можете выйти из xterm окна, закрыв окно, или набрать exit в bash prompt. Или вы можете ввести дополнительные команды по запросу.

Используйте ] bash - параметр init-файла с временным конвейером:

Это запустит сценарий в новом окне и даже даст вам возможность управлять окном после его завершения.

Однако новое окно не загрузится

TL; DR;

Используйте exec bash; или exec $ SHELL; в конце команды, чтобы держать терминал открытым после запуска

Подробная информация и пример тестового кода

Не существует ответа, показывающего exec bash как правильный ответ, но он должен быть, так что вот он. Этот ответ частично заимствован из ответа @ Karsvo , ответа @Stefano Palazo и комментария @Andrea Corbellini под ответом Стефано.

В моей системе (последний раз проверялся и проверялся) в Ubuntu 20.04), echo $ SHELL показывает, что переменная SHELL содержит / bin / bash . Однако где bash показывает, что исполняемый файл bash находится в / usr / bin / bash . НО, / user / bin / bash и / bin / bash являются идентичными исполняемыми файлами, что подтверждается наличием одинаковых sha256sum :

Следовательно, использование bash вместо $ SHELL идентичен. Кроме того, я определил, что все три из них в конце будут держать терминал открытым: bash , eval bash , exec bash , , но только последний, exec bash , позволит вам закрыть терминал без предупреждения о том, что процесс все еще запущен. Поэтому лучше всего использовать exec bash или exec $ SHELL , как говорит @AndreaCorbellini в своем комментарии.

Тест 1: это будет работать, как ожидалось

Вот что это может выглядеть так в случае использования сценария для открытия двух новых gnome-terminal вкладок, уже cd ed в вашем каталоге

Добавьте в конец вашего

ИЛИ: опять же, вы можете использовать exec $ SHELL вместо этого:

Затем в любой gnome-terminal уже открыт, переустановите свой

/ .bashrc , затем запустите эту команду с:

. и вы увидите исходную вкладку gnome-terminal плюс две новые вкладки, причем обе две новые вкладки уже cd ed в каталог

Если вы удалите exec bash; или exec $ SHELL; часть с конца каждого из однако приведенные выше команды, а затем повторно загрузите ваш файл

/ .bashrc , затем снова запустите команду open_default_tabs , вы увидите, что вкладки мигают, открываясь, а затем немедленно закрываясь. Все, что вы увидите, это пара быстрых вспышек. Часть exec bash; или exec $ SHELL; в конце требуется, чтобы эти новые вкладки оставались открытыми.

Тест 2: это доказывает, что exec bash; работает. НО, поведение gnome-terminal не совсем такое, как ожидалось. Чтобы решить эту проблему, см. Мои более-сложный ответ и обходной путь в моем другом ответе здесь .

Убедитесь, что some_dir существует, и сделайте test.sh исполняемый файл:

Обратите внимание на два окна (не вкладки, в данном случае из-за проблемы в gnome-terminal ), которые были только что открыты оставаться открытым . Удалите exec bash; выше, и вы увидите, что они не закрываются - они мгновенно закрываются - так быстро, что вы даже не увидите их открывающихся. Это доказывает, что exec bash; работает отлично. Поведение gnome-terminal не совсем такое, как ожидалось, но это не имеет ничего общего с exec bash; , который отлично работает. Опять же, см. мой другой ответ здесь для полного решения проблемы, специфичной для gnome-terminal в этом случае.

image


В прошлый раз мы говорили о работе с потоками ввода, вывода и ошибок в bash-скриптах, о дескрипторах файлов и о перенаправлении потоков. Сейчас вы знаете уже достаточно много для того, чтобы писать что-то своё. На данном этапе освоения bash у вас вполне могут возникнуть вопросы о том, как управлять работающими скриптами, как автоматизировать их запуск.

До сих пор мы вводили имена скриптов в командную строку и нажимали Enter, что приводило к немедленному запуску программ, но это — не единственный способ вызова сценариев. Сегодня мы поговорим о том как скрипт может работать с сигналами Linux, о различных подходах к запуску скриптов и к управлению ими во время работы.

Сигналы Linux

В Linux существует более трёх десятков сигналов, которые генерирует система или приложения. Вот список наиболее часто используемых, которые наверняка пригодятся при разработке сценариев командной строки.

Код сигнала
Название
Описание
1
SIGHUP
Закрытие терминала
2
SIGINT
Сигнал остановки процесса пользователем с терминала (CTRL + C)
3
SIGQUIT
Сигнал остановки процесса пользователем с терминала (CTRL + \) с дампом памяти
9
SIGKILL
Безусловное завершение процесса
15
SIGTERM
Сигнал запроса завершения процесса
17
SIGSTOP
Принудительная приостановка выполнения процесса, но не завершение его работы
18
SIGTSTP
Приостановка процесса с терминала (CTRL + Z), но не завершение работы
19
SIGCONT
Продолжение выполнения ранее остановленного процесса

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

Сигнал SIGINT приводит к временной остановке работы. Ядро Linux перестаёт выделять оболочке процессорное время. Когда это происходит, оболочка уведомляет процессы, отправляя им сигнал SIGINT .

Bash-скрипты не контролируют эти сигналы, но они могут распознавать их и выполнять некие команды для подготовки скрипта к последствиям, вызываемым сигналами.

Отправка сигналов скриптам

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

Завершение работы процесса

Комбинация клавиш CTRL + C генерирует сигнал SIGINT и отправляет его всем процессам, выполняющимся в оболочке, что приводит к завершению их работы.

Выполним в оболочке такую команду:


После этого завершим её работу комбинацией клавиш CTRL + C .


Завершение работы процесса с клавиатуры

Временная остановка процесса

Комбинация клавиш CTRL + Z позволяет сгенерировать сигнал SIGTSTP , который приостанавливает работу процесса, но не завершает его выполнение. Такой процесс остаётся в памяти, его работу можно возобновить. Выполним в оболочке команду:


И временно остановим её комбинацией клавиш CTRL + Z .


Приостановка процесса

Число в квадратных скобках — это номер задания, который оболочка назначает процессу. Оболочка рассматривает процессы, выполняющиеся в ней, как задания с уникальными номерами. Первому процессу назначается номер 1, второму — 2, и так далее.

Если вы приостановите задание, привязанное к оболочке, и попытаетесь выйти из неё, bash выдаст предупреждение.

Просмотреть приостановленные задания можно такой командой:


Список заданий

В колонке S , выводящей состояние процесса, для приостановленных процессов выводится T . Это указывает на то, что команда либо приостановлена, либо находится в состоянии трассировки.

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

Выглядит её вызов так:

Перехват сигналов

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

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

Рассмотрим пример, в котором показано, как при вызове команды trap задаётся код, который надо выполнить, и список сигналов, разделённых пробелами, которые мы хотим перехватить. В данном случае это всего один сигнал:


Перехват сигналов

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

Перехват сигнала выхода из скрипта

Перехватить сигнал выхода из скрипта можно, использовав при вызове команды trap имя сигнала EXIT :


Перехват сигнала выхода из скрипта

При выходе из скрипта, будь то нормальное завершение его работы или завершение, вызванное сигналом SIGINT , сработает перехват и оболочка исполнит команду echo .

Модификация перехваченных сигналов и отмена перехвата

Для модификации перехваченных скриптом сигналов можно выполнить команду trap с новыми параметрами:


Модификация перехвата сигналов

После модификации сигналы будут обрабатываться по-новому.

Перехват сигналов можно и отменить, для этого достаточно выполнить команду trap , передав ей двойное тире и имя сигнала:


Если скрипт получит сигнал до отмены перехвата, он обработает его так, как задано в действующей команде trap . Запустим скрипт:


И нажмём CTRL + C на клавиатуре.


Сигнал, перехваченный до отмены перехвата

Первое нажатие CTRL + C пришлось на момент исполнения скрипта, когда перехват сигнала был в силе, поэтому скрипт исполнил назначенную сигналу команду echo . После того, как исполнение дошло до команды отмены перехвата, команда CTRL + C сработала обычным образом, завершив работу скрипта.

Выполнение сценариев командной строки в фоновом режиме

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

Если вы видели список процессов, выводимый командой ps , вы могли заметить процессы, которые выполняются в фоне и не привязаны к терминалу.
Напишем такой скрипт:


Запустим его, указав после имени символ амперсанда ( & ):


Это приведёт к тому, что он будет запущен как фоновый процесс.


Запуск скрипта в фоновом режиме


Список процессов

При таком подходе, если выйти из терминала, скрипт, выполняющийся в фоне, так же завершит работу.

Что если нужно, чтобы скрипт продолжал работать и после закрытия терминала?

Выполнение скриптов, не завершающих работу при закрытии терминала

Скрипты можно выполнять в фоновых процессах даже после выхода из терминальной сессии. Для этого можно воспользоваться командой nohup . Эта команда позволяет запустить программу, блокируя сигналы SIGHUP , отправляемые процессу. В результате процесс будет исполняться даже при выходе из терминала, в котором он был запущен.

Применим эту методику при запуске нашего скрипта:


Вот что будет выведено в терминал.


Команда nohup

Обратите внимание на то, что при запуске нескольких скриптов из одной и той же директории то, что они выводят, попадёт в один файл nohup.out .

Просмотр заданий

Команда jobs позволяет просматривать текущие задания, которые выполняются в оболочке. Напишем такой скрипт:


И временно остановим комбинацией клавиш CTRL + Z .


Запуск и приостановка скрипта

Запустим тот же скрипт в фоновом режиме, при этом перенаправим вывод скрипта в файл так, чтобы он ничего не выводил на экране:


Выполнив теперь команду jobs , мы увидим сведения как о приостановленном скрипте, так и о том, который работает в фоне.


Получение сведений о скриптах

Ключ -l при вызове команды jobs указывает на то, что нам нужны сведения об ID процессов.

Перезапуск приостановленных заданий

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


Нажмём CTRL + Z , что временно остановит его выполнение. Выполним следующую команду:


Теперь скрипт выполняется в фоновом режиме.

Если у вас имеется несколько приостановленных заданий, для перезапуска конкретного задания команде bg можно передать его номер.

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

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

Linux предоставляет пару способов запуска bash-скриптов в заданное время. Это команда at и планировщик заданий cron .

Вызов команды at выглядит так:


Эта команда распознаёт множество форматов указания времени.

  • Стандартный, с указанием часов и минут, например — 10:15.
  • С использованием индикаторов AM/PM, до или после полудня, например — 10:15PM.
  • С использованием специальных имён, таких, как now , noon , midnight .
  • Стандартный формат указания даты, при котором дата записывается по шаблонам MMDDYY , MM/DD/YY , или DD.MM.YY .
  • Текстовое представление даты, например, Jul 4 или Dec 25 , при этом год можно указать, а можно обойтись и без него.
  • Запись вида now + 25 minutes .
  • Запись вида 10:15PM tomorrow .
  • Запись вида 10:15 + 7 days .


Планирование заданий с использованием команды at

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

Для того чтобы посмотреть список заданий, ожидающих выполнения, можно воспользоваться командой atq :


Список заданий, ожидающих выполнения

Удаление заданий, ожидающих выполнения

Удалить задание, ожидающее выполнения, позволяет команда atrm . При её вызове указывают номер задания:


Удаление задания

Запуск скриптов по расписанию

Планирование однократного запуска скриптов с использованием команды at способно облегчить жизнь во многих ситуациях. Но как быть, если нужно, чтобы скрипт выполнялся в одно и то же время ежедневно, или раз в неделю, или раз в месяц?

В Linux имеется утилита crontab , позволяющая планировать запуск скриптов, которые нужно выполнять регулярно.

Crontab выполняется в фоне и, основываясь на данных в так называемых cron-таблицах, запускает задания по расписанию.

Для того, чтобы просмотреть существующую таблицу заданий cron , воспользуйтесь такой командой:


При планировании запуска скрипта по расписанию crontab принимает данные о том, когда нужно выполнить задание, в таком формате:


Например, если надо, чтобы некий скрипт с именем command выполнялся ежедневно в 10:30, этому будет соответствовать такая запись в таблице заданий:


Здесь универсальный символ « * », использованный для полей, задающих день месяца, месяц и день недели, указывает на то, что cron должен выполнять команду каждый день каждого месяца в 10:30.

Если, например, надо, чтобы скрипт запускался в 4:30PM каждый понедельник, понадобится создать в таблице заданий такую запись:


Нумерация дней недели начинается с 0, 0 означает воскресенье, 6 — субботу. Вот ещё один пример. Здесь команда будет выполняться в 12 часов дня в первый день каждого месяца.


Нумерация месяцев начинается с 1.
Для того чтобы добавить запись в таблицу, нужно вызвать crontab с ключом -e :


Затем можно вводить команды формирования расписания:


Благодаря этой команде скрипт будет вызываться ежедневно в 10:30. Если вы столкнётесь с ошибкой «Resource temporarily unavailable», выполните нижеприведённую команду с правами root-пользователя:


Организовать периодический запуск скриптов с использованием cron можно ещё проще, воспользовавшись несколькими специальными директориями:


Если поместить файл скрипта в одну из них, это приведёт, соответственно, к его ежечасному, ежедневному, еженедельному или ежемесячному запуску.

Запуск скриптов при входе в систему и при запуске оболочки

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


Для того, чтобы запускать скрипт при входе в систему, поместите его вызов в файл .bash_profile .

А как насчёт запуска скриптов при открытии терминала? Организовать это поможет файл .bashrc .

Итоги

Сегодня мы разобрали вопросы, касающиеся управления жизненным циклом сценариев, поговорили о том, как запускать скрипты в фоне, как планировать их выполнение по расписанию. В следующий раз читайте о функциях в bash-скриптах и о разработке библиотек.

Читайте также: