Issue
Is it possible to capture the exit code from a process running on, e.g. ExecStart
in a systemd service unit? I want to check, if the process exited okay or if an error occurred.
After reading the systemd.service and systemd.exec docs, I thought $SERVICE_RESULT
$EXIT_CODE
and / or $EXIT_STATUS
might help. But to no avail.
Given this test unit:
[Unit]
Description=Testing Run Order
[Service]
Type=simple
Environment=HELLO=WORLD
ExecStartPre=/bin/echo [StartPre] $MAINPID $SERVICE_RESULT $EXIT_CODE $EXIT_STATUS
ExecStartPost=/bin/echo [StartPost] $MAINPID $SERVICE_RESULT $EXIT_CODE $EXIT_STATUS
ExecStart=/bin/sleep 2
ExecStop=/bin/env
ExecStop=/bin/echo [Stop] $MAINPID $SERVICE_RESULT $EXIT_CODE $EXIT_STATUS
ExecStopPost=/bin/echo [StopPost] $MAINPID $SERVICE_RESULT $EXIT_CODE $EXIT_STATUS
I get the following output:
Aug 30 08:37:26 localhost.localdomain systemd[1]: Starting Testing Run Order...
Aug 30 08:37:26 localhost.localdomain echo[3458]: [StartPre]
Aug 30 08:37:26 localhost.localdomain systemd[1]: Started Testing service metrics.
Aug 30 08:37:26 localhost.localdomain echo[3460]: [StartPost] 3459
Aug 30 08:37:27 localhost.localdomain env[3465]: LANG=en_US.UTF-8
Aug 30 08:37:27 localhost.localdomain env[3465]: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
Aug 30 08:37:27 localhost.localdomain env[3465]: HELLO=WORLD
Aug 30 08:37:27 localhost.localdomain echo[3467]: [Stop]
Aug 30 08:37:27 localhost.localdomain echo[3469]: [StopPost]
So nothing. I'm currently stuck with systemd 219
(+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ -LZ4 -SECCOMP +BLKID +ELFUTILS +KMOD +IDN) on Centos7.
Solution
$EXIT_CODE
and $EXIT_STATUS
were only added in systemd v232. If you’re stuck with an older version, you’ll have to work around it, perhaps with something like this (untested):
ExitStart=/bin/sh -c '/* normal command goes here */; echo $? > /tmp/my-service.exit'
ExecStopPost=/bin/sh -c 'EXIT_STATUS=$(cat /tmp/my-service.exit); /* rest of command goes here */'
A side note: when you write something like
ExecStop=/bin/echo [Stop] $MAINPID $SERVICE_RESULT $EXIT_CODE $EXIT_STATUS
in your test unit, those variables are substituted by systemd. To check the environment of the actual process, use a shell (as above) or a command like env
(as you did for one of the ExecStop
lines).
Answered By - Lucas Werkmeister Answer Checked By - Katrina (WPSolving Volunteer)