获取“systemd-run <command />”结果状态代码的简便方法是什么?

时间:2015-08-08 07:55:37

标签: linux virtualization systemd

除非调用运行时systemd单元失败,否则systemd-run <command>的结果状态代码似乎始终为0

示例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

我可以知道命令是否成功完成,如下所示。

示例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

但返回的代码始终为3,因为它是systemctl status命令的结果。 最后,我必须做如下的事情;

示例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

这太奇怪了!

我使用systemd-run并获取返回代码的原因是我想在正在运行的systemd-nspawn ed容器环境中执行一个或多个命令(systemd-run --machine=my_container)。

总结一下,我想在systemd-nspawn ed容器中执行一个命令,并获得与docker exec一样的结果代码(没有machinectl login,因为我想通过非执行这么多命令 - 交互式脚本文件)。 有谁可以让我知道简单的方法来获得它?

3 个答案:

答案 0 :(得分:1)

  

似乎systemd-run的结果状态代码始终为0   除非调用运行时systemd单元失败。

是的,这是正确的和预期的行为..在这种特殊情况下,systemd-run不会自行运行命令。它使用您选择的参数创建,验证和排队瞬态.service文件,然后由&#34; - system&#34;或&#34; - 用户&#34;服务经理。 得到你想要的...... TL; DR

# systemd-run --scope /bin/true
# echo $?
0
# systemd-run --scope /bin/false
# echo $?
1

请注意,在这种情况下,作用域单元将继承调用脚本的环境,并且仅在命令完成时才返回执行..

答案 1 :(得分:1)

您需要使用--remain-after-exit告诉Systemd保留服务单元,以便可以获取其状态。

# 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

答案 2 :(得分:0)

我不知道基于systemd的虚拟化的细节,但是如果您需要先前命令的返回代码来决定是否运行更多命令,或者决定运行哪些其他命令,那么这是一个简单的解决方案可能是将您的命令(前缀为sudo systemd-run所有返回代码查询和根据决策逻辑放入脚本中。

然后只需使用sudo systemd-run /path/to/that/script调用该脚本。