获取 "systemd-run <command>" 结果状态代码的简便方法?

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

似乎 systemd-run <command> 的结果状态代码总是 0 除非调用 运行-time systemd 单元失败。

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

我可以通过以下方式知道命令是否成功完成。

例二:

$ systemctl status $(sudo systemd-run /usr/bin/true 2>&1 | awk '{ print  }' | 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  }' | 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

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

示例 3:

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

这也太奇怪了吧!

之所以使用systemd-run并得到return代码是因为我想在运行ning systemd-nspawned容器环境中执行一个或多个命令(作者 systemd-run --machine=my_container)。

总而言之,我想在 systemd-nspawned 容器中执行命令并获得结果代码,就像 docker exec 一样(没有 machinectl login 因为我想执行这么多命令通过非交互式脚本文件)。 谁能告诉我获得它的简单方法吗?

我不知道基于 systemd 的虚拟化的细节,但是如果您需要 return 先前命令的代码来决定是否要 运行 进一步的命令,或者决定 运行 的进一步命令,一个简单的解决方案可能是将您的命令( 而不是 sudo systemd-run 为前缀) 所有 return 代码查询和根据决策逻辑写入脚本。

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

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

是的,这是正确的和预期的行为。在这种特殊情况下,systemd-运行 本身并不 运行 命令。它使用您选择的参数创建、验证和排队一个临时的 .service 文件,然后由“--system”或“--user”服务管理器启动。 为了得到你想要的.. TL;DR

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

请注意,在这种情况下,范围单元将继承调用脚本的环境并仅在命令完成时执行 returns..

您需要使用--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