创建一个开机后只运行一次的任务

写 一个 linux systemd 服务, 开机后只运行一次的, 运行后自动删除服务, 用来初始化系统

  1. [Unit]
  2. Description=Run once at startup
  3. [Service]
  4. Type=oneshot
  5. ExecStart=/root/script.sh
  6. [Install]
  7. WantedBy=multi-user.target

script.sh:

  1. #!/bin/bash
  2. # Initialization code goes here
  3. # Once finished, delete this service
  4. systemctl disable run-once-at-startup.service
  5. rm /etc/systemd/system/run-once-at-startup.service

systemd-run

systemd-run 是一个命令行工具,允许您在 systemd 管理的临时服务单元(Transient service units)中运行命令和进程。
systemd-run 的一些重要特性包括:

  • 它能将单个命令或整个进程链作为独立的服务运行。这使得它成为在控制服务和任务的生命周期方面的强大工具。
  • 它可以用于创建临时定时任务,类似于 atcron,但是使用的是 systemd 服务管理。
  • 它支持各种服务设置,包括设定资源限制、设置环境变量、定义依赖关系等。

基本的命令格式为:

  1. systemd-run [OPTIONS...] {COMMAND} [ARGS...]

在这个命令中,OPTIONS... 是指向 systemd-run 提供的选项,而 {COMMAND}[ARGS...] 分别是你想要运行的命令及其参数。
这里有一些常见的 systemd-run 选项:

  • --unit=UNIT:为创建的服务单元指定名称。
  • --scope:将命令作为 scope 而非 service 运行。
  • --user:以当前用户身份运行命令,而非 root 用户。
  • --on-active=TIME--on-boot=TIME--on-unit-active=TIME--on-unit-inactive=TIME:创建定时任务。

例如,如果你想要创建一个在一分钟后执行的定时任务,你可以使用下面的命令:

  1. systemd-run --user --on-active=1m /path/to/command args

在这个命令中,--user 选项告诉 systemd-run 以当前用户身份运行命令,--on-active=1m 指定任务将在一分钟后执行,/path/to/command args 是你想要执行的命令及其参数。

最后,为了使用 systemd-run,你需要具有适当的系统权限,通常意味着你需要有 root 访问权限。对于那些不具有 root 访问权限的用户,可以使用 --user 选项来运行任务,这个选项将命令作为当前用户运行,但这可能会限制其功能和权限。

在docker 容器内如何使用 systemd

如果你确实需要在 Docker 容器内运行 systemd,你可以使用一个专门配置过的 Docker 镜像,如 centos/systemd。以下是在 Docker 容器内运行 systemd 的步骤:

  1. 首先,你需要一个支持运行 systemd 的 Docker 镜像。例如,你可以使用 CentOS 提供的 systemd 镜像,可以通过以下命令来拉取这个镜像:
  1. docker pull centos/systemd
  1. 然后,你可以使用以下命令启动一个包含 systemd 的 Docker 容器:
  1. docker run -d --privileged --name centos_systemd centos/systemd /sbin/init

在这个命令中:

  • -d 参数使容器在后台运行。
  • --privileged 参数给容器完全的主机访问权限。这是运行 systemd 所必需的。
  • --name 参数给容器一个名称。
  • /sbin/init 是容器启动时要运行的命令。在这种情况下,我们要启动的是 systemd。
  1. 在容器中运行命令:

你可以使用 docker exec 命令在已经运行的容器中执行命令。例如,你可以使用以下命令在容器中运行 systemctl

  1. docker exec -it centos_systemd /bin/bash
  2. systemctl status

请注意,这只是在 Docker 容器中运行 systemd 的一种方式,而且需要你具有相应的权限和安全措施。在容器中运行 systemd 可能会引入额外的复杂性和安全问题,因此应该谨慎使用。

另外,这并不是 Docker 的推荐用法。Docker 更适合运行单个应用或服务,而不是完整的操作系统。如果你发现自己需要在容器中运行 systemd,那么可能是你的用例更适合使用其他的虚拟化技术,如虚拟机。

创建一个服务用于测试

  1. systemd-run \
  2. --unit=test.service \
  3. --remain-after-exit \
  4. --property=LimitNOFILE=524288 \
  5. bash -c 'while true; do sleep 3; done'