Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Easy way to get result status code of "systemd-run <command>"?

It seems the result status code of systemd-run <command> is always 0 unless invoking the run-time systemd unit fails.

Example 1:

$ sudo systemd-run /usr/bin/true
Running as unit run-12255.service.
$ echo $?
0

$ sudo systemd-run /usr/bin/false
Running as unit run-12258.service.
$ echo $?
0

I can know whether the command was successfully done or not as follows.

Example 2:

$ systemctl status $(sudo systemd-run /usr/bin/true 2>&1 | awk '{ print $4 }' | sed -e 's/\.$//')
● run-13004.service
   Loaded: not-found (Reason: No such file or directory)
   Active: inactive (dead)
$ echo $?
3

$ systemctl status $(sudo systemd-run /usr/bin/false 2>&1 | awk '{ print $4 }' | sed -e 's/\.$//')
● run-13021.service - /usr/bin/false
   Loaded: loaded (/run/systemd/system/run-13021.service; static; vendor preset: disabled)
  Drop-In: /run/systemd/system/run-13021.service.d
           └─50-Description.conf, 50-ExecStart.conf
   Active: failed (Result: exit-code) since Sat 2015-08-08 07:31:10 UTC; 15ms ago
  Process: 13024 ExecStart=/usr/bin/false (code=exited, status=1/FAILURE)
 Main PID: 13024 (code=exited, status=1/FAILURE)
$ echo $?
3

But the returned code is always 3 since it is the result of systemctl status command. Finally, I have to do as follows;

Example 3:

$ systemctl status $(sudo systemd-run /usr/bin/true 2>&1 | awk '{ print $4 }' | sed -e 's/\.$//') | (egrep -m 1 -o 'code=exited, status=[0-9]+'| egrep -o '[0-9]+') || echo '0'
0

$ systemctl status $(sudo systemd-run /usr/bin/false 2>&1 | awk '{ print $4 }' | sed -e 's/\.$//') | (egrep -m 1 -o 'code=exited, status=[0-9]+'| egrep -o '[0-9]+') || echo '0'
1

This is too weird!

The reason why I use systemd-run and get the return code is that I want to execute one or more command in a running systemd-nspawned container environment (by systemd-run --machine=my_container).

To summarize, I want to execute a command in a systemd-nspawned container and get the result code just like docker exec (without machinectl login since I want to execute so many commands by non-interactive script file). Can anyone kindly let me know easy way to get it?

like image 528
takaomag Avatar asked Sep 04 '25 01:09

takaomag


1 Answers

You need to to use --remain-after-exit to tell Systemd to keep service unit, so that it is possible to get its status.

# systemd-run  --unit=kek$RANDOM --remain-after-exit     bash -c 'sleep 2; id; exit 216'
Running as unit kek30537.service.

# systemctl show  kek30537.service  -p ExecMainStatus
ExecMainStatus=216
like image 165
Pavel Piatruk Avatar answered Sep 07 '25 12:09

Pavel Piatruk