Выполнение сценариев командной строки в фоновом режиме
Иногда bash-скриптам требуется немало времени для выполнения некоей задачи. При этом вам может понадобиться возможность нормально работать в командной строке, не дожидаясь завершения скрипта. Реализовать это не так уж и сложно.
Если вы видели список процессов, выводимый командой ps, вы могли заметить процессы, которые выполняются в фоне и не привязаны к терминалу.
Напишем такой скрипт:
#!/bin/bash
count=1
while [ $count -le 10 ]
do
sleep 1
count=$(( $count + 1 ))
done
Запустим его, указав после имени символ амперсанда (&):
$ ./myscipt &
Это приведёт к тому, что он будет запущен как фоновый процесс.
Запуск скрипта в фоновом режиме
Скрипт будет запущен в фоновом процессе, в терминал выведется его идентификатор, а когда его выполнение завершится, вы увидите сообщение об этом.
Обратите внимание на то, что хотя скрипт выполняется в фоне, он продолжает использовать терминал для вывода сообщений в STDOUT и STDERR, то есть, выводимый им текст или сообщения об ошибках можно будет увидеть в терминале.
Список процессов
При таком подходе, если выйти из терминала, скрипт, выполняющийся в фоне, так же завершит работу.
Что если нужно, чтобы скрипт продолжал работать и после закрытия терминала?
Выполнение скриптов, не завершающих работу при закрытии терминала
Скрипты можно выполнять в фоновых процессах даже после выхода из терминальной сессии. Для этого можно воспользоваться командой nohup. Эта команда позволяет запустить программу, блокируя сигналы SIGHUP, отправляемые процессу. В результате процесс будет исполняться даже при выходе из терминала, в котором он был запущен.
Применим эту методику при запуске нашего скрипта:
nohup ./myscript &
Вот что будет выведено в терминал.
Команда nohup
Команда nohup отвязывает процесс от терминала. Это означает, что процесс потеряет ссылки на STDOUT и STDERR. Для того, чтобы не потерять данные, выводимые скриптом, nohup автоматически перенаправляет сообщения, поступающие в STDOUT и в STDERR, в файл nohup.out.
Обратите внимание на то, что при запуске нескольких скриптов из одной и той же директории то, что они выводят, попадёт в один файл nohup.out.
Просмотр заданий
Команда jobs позволяет просматривать текущие задания, которые выполняются в оболочке. Напишем такой скрипт:
#!/bin/bash
count=1
while [ $count -le 10 ]
do
echo "Loop #$count"
sleep 10
count=$(( $count + 1 ))
done
Запустим его:
$ ./myscript
И временно остановим комбинацией клавиш CTRL + Z.
Запуск и приостановка скрипта
Запустим тот же скрипт в фоновом режиме, при этом перенаправим вывод скрипта в файл так, чтобы он ничего не выводил на экране:
$ ./myscript > outfile &
Выполнив теперь команду jobs, мы увидим сведения как о приостановленном скрипте, так и о том, который работает в фоне.
Получение сведений о скриптах
Ключ -l при вызове команды jobs указывает на то, что нам нужны сведения об ID процессов.
Перезапуск приостановленных заданий
Для того, чтобы перезапустить скрипт в фоновом режиме, можно воспользоваться командой bg.
Запустим скрипт:
$ ./myscript
Нажмём CTRL + Z, что временно остановит его выполнение. Выполним следующую команду:
$ bg
Команда bg
Теперь скрипт выполняется в фоновом режиме.
Если у вас имеется несколько приостановленных заданий, для перезапуска конкретного задания команде bg можно передать его номер.
Для перезапуска задания в обычном режиме воспользуйтесь командой fg:
$ fg 1
Планирование запуска скриптов
Linux предоставляет пару способов запуска bash-скриптов в заданное время. Это команда at и планировщик заданий cron.
Вызов команды at выглядит так:
at [-f filename] time
Эта команда распознаёт множество форматов указания времени.