Created by [CecilWesterhof]. In the past I wrote a script to check if systemd services where running and if not tried to restart them. I rewrote this script into Tcl and added some functionalities. The main code is: ====== init foreach service ${services} { debugOutput ${debug} "Checking: ${service}" if {! [isServiceActive ${service}]} { puts "${service} is not running" giveStatus ${service} if {[startService ${service}]} { puts " ${service} started" } else { puts " ${service} NOT started" giveStatus } } } ====== It checks all the services and if one is not running it tries to start it. To check if a service is running I use: ====== proc isServiceActive {service} { if {[catch {exec systemctl status ${service}} result]} { if {([lindex ${::errorCode} 0] == "CHILDSTATUS") && ([lindex ${::errorCode} 2] == 3)} { return False } error ${result} } return True } ====== The call 'systemctl status SERVICE' returns 0 if the service is running and 3 if it is not running. Anything else is an error. If the service is not running I give the status: ====== proc giveStatus {service} { set status [getCleanOutput "systemctl status ${service}" {3}] puts "\nStatus:\n${status}" } ====== Which uses: [Getting Cleaned Up Output from a Command]. It then tries to start the service: ====== proc startService {service} { puts "\nTrying to start:" exec systemctl start ${service} sleep ${::startTime} isServiceActive ${service} } ====== If that is successful it says that, otherwise it says it was not successful and displays the status of the service. The initialisation is done with: ====== proc init {} { set ::debug False set ::startTime 5 set parameters ${::argv} switch [lindex ${parameters} 0] { --debug { set ::debug True set parameters [lrange ${parameters} 1 end] } --active { puts "Active services:" foreach service [getServices] { puts " ${service}" } exit } --inactive { puts "Inactive services:" foreach service [getServices F] { puts " ${service}" } exit } } if {[llength ${parameters}] > 0} { set ::services ${parameters} } else { set ::services [getServices] } } ====== Default the services to check are retrieved from the database, but you can also give them on the command-line. It is possible to activate debugging. And a list with the active or inactive services can be shown. To get the list with (in)active services: ====== proc getServices {{active T}} { getDefaultDB set services [db eval { SELECT service FROM checkServices WHERE active = :active ORDER BY service }] db close return ${services} } ====== I will share getDefaultDB later. To create the table: ====== CREATE TABLE checkServices ( service TEXT PRIMARY KEY, active TEXT NOT NULL DEFAULT 'T' CHECK(active IN ('T', 'F')) ); ====== To sleep a few seconds (to give the service time to start): ====== proc sleep {seconds} { after [expr {${seconds} * 1000}] } ====== The proc debugOutput is very simple: ====== proc debugOutput {giveOutput Message} { if {${giveOutput}} { puts ${Message} } } ====== ---- As always: comments, tips and questions are appreciated. <>Linux | System Maintenance | Utilities