- systemctl (system control) без запущенных аргументов выдает список systemd объектов/UNIT (mount, target, service, socket, timers, etc) запущенных в системе. с флагом —type <UNIT> можно отфильтровать конкретные объекты.
# systemctl UNIT LOAD ACTIVE SUB DESCRIPTION proc-sys-fs-binfmt_misc.automount loaded active waiting Arbitrary Executable File Formats File System Automount Point sys-devices-pci0000:00-0000:00:07.1-ata2-host1-target1:0:0-1:0:0:0-block-sr0.device loaded active plugged VMware_Virtual_IDE_CDROM_Drive sys-devices-pci0000:00-0000:00:10.0-host2-target2:0:0-2:0:0:0-block-sda-sda1.device loaded active plugged Virtual_disk 1 sys-devices-pci0000:00-0000:00:10.0-host2-target2:0:0-2:0:0:0-block-sda-sda2.device loaded active plugged Virtual_disk 2 sys-devices-pci0000:00-0000:00:10.0-host2-target2:0:0-2:0:0:0-block-sda-sda5.device loaded active plugged Virtual_disk 5 sys-devices-pci0000:00-0000:00:10.0-host2-target2:0:0-2:0:0:0-block-sda.device loaded active plugged Virtual_disk sys-devices-pci0000:00-0000:00:11.0-0000:02:00.0-net-ens32.device loaded active plugged 82545EM Gigabit Ethernet Controller (Copper) (PRO/1000 MT Single Port Adapter) sys-devices-pci0000:00-0000:00:11.0-0000:02:01.0-net-ens33.device loaded active plugged 82545EM Gigabit Ethernet Controller (Copper) (PRO/1000 MT Single Port Adapter) sys-devices-pci0000:00-0000:00:11.0-0000:02:02.0-net-ens34.device loaded active plugged 82545EM Gigabit Ethernet Controller (Copper) (PRO/1000 MT Single Port Adapter) sys-devices-platform-floppy.0-block-fd0.device loaded active plugged /sys/devices/platform/floppy.0/block/fd0 ... # systemctl --type=mount UNIT LOAD ACTIVE SUB DESCRIPTION -.mount loaded active mounted / dev-hugepages.mount loaded active mounted Huge Pages File System dev-mqueue.mount loaded active mounted POSIX Message Queue File Syst run-netns-VRF1.mount loaded active mounted /run/netns/VRF1 run-netns-VRF2.mount loaded active mounted /run/netns/VRF2 run-netns.mount loaded active mounted /run/netns run-user-0.mount loaded active mounted /run/user/0 sys-kernel-debug.mount loaded active mounted Kernel Debug File System
Все управляющие программы для роботов по сути демоны/службы – работают в бесконечном цикле.
В CentOS, в отличии от Ubuntu, по умолчанию нет Start-stop-daemon для запуска своих процессов в виде демонов. При его наличии запуск приложения в виде демона решается простой командой (главное чтобы скрипт был исполняемым :)).
start-stop-daemon -Sbvx /home/redkin_p/bin/test.rb
Для того чтобы сделать это в CentOS (справедливо и для Debian) есть такие варианты:
0) screen
1) Запустить приложение через nohup. Или в сессии screen/tmux (о screen).
nohup — UNIX-утилита, запускающая указанную команду с игнорированием сигналов потери связи (SIGHUP). Таким образом, команда будет продолжать выполняться в фоновом режиме и после того, как пользователь выйдет из системы. Позволяет не запускать start-stop-daemon, делать сервисы и вообще что-либо. Идет из коробки во всех известных дистрибутивах Linux. Еще круто, что вывод она пишет в отдельный файл - nohup.out (если не нужен - можно дропнуть через редирект &>/dev/null) nohup bin/sms2.rb nohup nmap -sP 10.3.0.0/20 nohup ip netns exec VRF1 ping 172.17.0.2 >ping_res_va # по умолчанию STDOUT сохраняется в файле nohup.out
2) собрать start-stop-daemon для CentOS. Как по мне очень плохое решение (но, возможно, в 2011 единственное) – требует компилятора, компиляции и прочих штук очень долгих и несущих существенные изменений в систему (зависимые системные библиотеки).
3) Перевести активное приложение/процесс с отвязкой от терминала можно с использованием hotkey по сворачиванию + переводу в background + disown процеса
1) Ctrl+Z to stop (pause) the program and get back to the shell. 2) bg to run it in the background. 3) disown -h [job-spec] where [job-spec] is the job number (like %1 for the first running job; find about your number with the jobs command) so that the job isn't killed when the terminal closes. Команда disown является встроенной командой таких командных оболочек, как Bash, Zsh и Ksh и позволяет убрать заданную задачу из таблицы задач командной оболочки. Это делается для того заблокировать отправку системного сигнала SIGHUP запущенному с помощью командной оболочки и исполняющемуся в фоновом режиме процессу при завершении работы командной оболочки. В отличие от команды nohup, рассматриваемая команда может использоваться в любой момент после создания задачи, а не до только при ее создании и не отсоединяет стандартные потоки ввода, вывода и ошибок исполняющегося процесса от командной оболочки.
4) Сделать сервис в system.d. Прекрасное и самое правильное решение. Немного сложнее start-stop-daemon (и, тем более, nohup), но лучше т.к. позволяет стандартно добавить сервис в автозагрузку, следить по аналогии с другими сервисами за работоспособностью, стандартно перезагружать и прочее.
https://scottlinux.com/2014/12/08/how-to-create-a-systemd-service-in-linux-centos-7/ https://unix.stackexchange.com/questions/236084/how-do-i-create-a-service-for-a-shell-script-so-i-can-start-and-stop-it-like-a-d
управление сервисами sysvinit
Смотрим какие сервисы есть в автозапуске
ls /etc/rc.d/rc3.d # для runlevel 3 ls /etc/rc.d/init.d # сервисы могут быть тут, а в runlevel ссылки на эти скрипты chkconfig —list # для всех runlevel
Включение/отключение в автозапуск сервиса для runlevel по умолчанию (2 3 4 5) или для конкретных runlevel. Chkconfig позволил отказаться от устаревшего подхода подкладывания файлов в директории rc.d для соответствующих runlevel (если скрипт подложен – запускается, если нет – не запускается).
sudo chkconfig httpd on sudo chkconfig httpd off sudo chkconfig —level 35 httpd on
Запуск/отключение/рестарт/просмотр статуса сервиса
sudo service httpd status sudo service httpd start sudo service httpd stop sudo service httpd restart
Пошагово создание сервиса в systemd
Аналог service файла ниже создается обычно при установке софта, описано создание своего сервиса.
1) Создаем файл с сервисом, называем как хотим, на конце должно быть “service”. Указываем target в котором будет запускаться сервис (подробнее в wants runlevel). Опционально указываем
- [Unit] After=<target> – сервис будет запущен только после запуска (after) указанного, например для сетевых сервисов логично “After=Network.target”.
- [Service]
- User=<user> – сервис по умолчанию запускается из под root, можно указать конкретного
- WorkingDirectory=<dir>
- Restart=<always> – автоперезагрузка сервиса при падении
$ cat /etc/systemd/system/test_service.service [Unit] Description=test_service.rb After=Network.target [Service] Type=simple ExecStart=/usr/bin/test_service.rb <options> [Install] WantedBy=multi-user.target
Для передачи переменных (напр. указываем название файла вывода от времени запуска сервиса) можно вызывать утилиту через /bin/bash. Пример: запускаем tcpdump, имя файла с дампом содержит дату/время запуска.
ExecStart=/bin/bash -c "test=$(/usr/bin/date | tr ' :' '.'); /usr/sbin/tcpdump -n -w /opt/logs/$test.pcap"
2) Перезагружаем службу демонов или включаем конкретный сервис (второе не использовал, но должно работать)
sudo systemctl daemon-reload sudo systemctl enable test_service
3) Стартуем наш сервис (так же start/stop)
sudo systemctl start test_service
4) Проверяем статус (тут можно посмотреть и текущий и включен ли автостарт). Тут так же видим последние сообщения от нашей программы/скрипта. Для просмотра всех сообщений смотрим journalctl (journald).
sudo systemctl status test_service sudo journalctl -u test_service
5) Добавляем в автозагрузку через enable (можно так же использовать множество других способов, напр. добавив команду start сервиса в /etc/rc.local, но самый правильный через systemctl; offtop: при использовании rc.local нужно не забывать добавлять shebang и права на исполнение). Флаг –now при использовании совместно с enable позволяет запустить службу, даже если ранее мы ее не запустили через start (в случае использования с disable отключает). Помимо добавления в автозагрузку systemd команда так же на всякий случай синхронизирует состояние сервиса в sysVinit.
sudo systemctl enable test_service sudo systemctl enable --now open-vm-tools # systemctl enable ssh Synchronizing state of ssh.service with SysV service script with /lib/systemd/systemd-sysv-install. Executing: /lib/systemd/systemd-sysv-install enable ssh
Так же можно управлять текущим состоянием сервиса start/stop/restart.
sudo systemctl start test_service sudo systemctl stop test_service sudo systemctl restart test_service
Enjoy
Типы сервисов в system.d
Выше рассмотрен простой типовой случай, когда используется тип сервиса simple, но возможно так же использовать oneshot и forking.
- Forking: systemd считает службу запущенной после того, как процесс разветвляется с завершением родительского процесса. Нужен для работы с приложениями, которые создают дочерние процессы при запуске (напр. worker’ы), а сами при этом отключаются – используется для запуска классических демонов за исключением тех случаев, когда в таком поведении процесса нет необходимости. Можно указать параметр PIDFile=, чтобы systemd мог отслеживать основной процесс. Oneshot и forking для таких задач подходят плохо, они оба предназначены для работы именно с тем процессом, который запускается
Both Type=oneshot and Type=simple units ignore any children of the first process, so do not use these modes with forking processes
- Simple (по умолчанию): systemd запустит эту службу незамедлительно. Процесс при этом не должен разветвляться (fork). Если после данной службы должны запускаться другие, то этот тип использовать не стоит (исключение — служба использует сокетную активацию).
- Oneshot: удобен для сценариев, которые выполняют одно задание и завершаются. Примеры использования.
Если задать параметр RemainAfterExit=yes, то systemd будет считать процесс активным даже после его завершения.
Questions
The command dbmaint & was used to run dbmaint in the background. However, dbmaint is terminated after logging out of the system. Which alternative dbmaint invocation lets dbmaint continue to run even when the user running the program logs out?
A. job –b dmaint
B. dbmaint &>/dev/pts/null
C. nohup dbmaint &
D. bg dbmaint
E. wait dbmaint
Answer: C The correct answer is nohup dbmaint & The reason for this is nohup (“no hangup”) detaches dbmaint from the user who started it, and the & at the end tells the console to run dbmaint in the background.