如何在“systemd”服务文件中获取机器 IP 地址

如何在“systemd”服务文件中获取机器 IP 地址

我需要获取机器的 IP 并在我的服务中使用它:

[Unit]
Description=Redmine server
After=syslog.target
After=network.target

[Service]
Type=simple
User=redmine
Group=redmine
ip="$(/sbin/ip -o -4 addr list eno16777736 | awk '{print $4}' | cut -d/ -f1)"
ExecStart=/usr/bin/ruby /home/redmine/redmine/bin/rails server webrick -e production -b $ip -p 3000

# Give a reasonable amount of time for the server to start up/shut down
TimeoutSec=300

[Install]
WantedBy=multi-user.target

我怎样才能在systemd服务文件并获取其结果:

ip=$(/sbin/ip -o -4 addr list eno16777736 | awk '{print $4}' | cut -d/ -f1)

为了使用它的结果信息xxx.xxx.xxx.xxx,像这样:

ExecStart=/usr/bin/ruby /home/redmine/redmine/bin/rails server webrick -e production -p 3000 -b $ip

答案1

使用 获取机器主机名systemd

虽然我不太熟悉systemd看着这个教程网站以及官方systemd手册页,你似乎正在寻找一个“说明符”值:

许多设置解析说明符,可用于编写引用运行时或单元参数的通用单元文件,这些参数在加载单元文件时被替换。

我认为在这里起作用的特定说明%H符是“主机名”,描述如下:

加载单元配置时正在运行的系统的主机名。

因此,请检查您的示例systemd脚本,将您的[Service]块更改为如下形式:

[Service]
Type=simple
User=redmine
Group=redmine
ExecStart=/usr/bin/ruby /home/redmine/redmine/bin/rails server webrick -e production -b %H -p 3000

请注意,带有赋值的行ip=()已消失,并且ExecStart命令现在使用%H而不是$ip

使用 获取 IP 地址 的一个想法systemd

话虽如此,似乎systemd仅通过“说明符”提供主机名%H。如果你问我,这很奇怪。因此,虽然我对 并没有深入的经验systemd,但我相信我明白可以做些什么来实现这篇文章的目标。

关键是设置一个EnvironmentFile用于systemd读取的。了解如何使用EnvironmentFile这个网站上

假设您创建了一个像这样的简单 Bash 脚本;让我们给它命名write_ip_to_file.sh并随意更改 IP 地址获取逻辑以ip=$()匹配您的设置:

#!/bin/bash
ip=$(/sbin/ifconfig eth0 | awk '/inet addr/ {split ($2,A,":"); print A[2]}');
echo IP=$ip > ~/ip.txt;

这样做的目的是将 IP 地址输出eth0到主目录中的文本文件中ip.txt。格式如下:

IP=123.456.789.0

明白了吗?很好。现在,在您的systemd脚本中,将您的[Service]块更改为如下内容;确保设置为与保存[your username]目录的用户名匹配:ip.txt

[Service]
Type=simple
User=redmine
Group=redmine
EnvironmentFile=/home/[your username]/ip.txt
ExecStart=/usr/bin/ruby /home/redmine/redmine/bin/rails server webrick -e production -b $IP -p 3000

它会加载配置ip.txt并分配$IP123.456.789.0。我相信这就是你要找的。

这里的关键因素是write_ip_to_file.sh在启动时运行,或者甚至通过systemd脚本本身运行。

使用 获取 IP 地址的另一种想法systemd

但话虽如此,我有一个更好的主意(如果可行的话):将整个ExecStart命令移到名为的 Bash 文件中redmine_start.sh,并确保系统可以读取和执行它。的内容redmine_start.sh如下;请随意更改 IP 地址获取逻辑以ip=$()匹配您的设置:

#!/bin/bash
ip=$(/sbin/ifconfig eth0 | awk '/inet addr/ {split ($2,A,":"); print A[2]}');
/usr/bin/ruby /home/redmine/redmine/bin/rails server webrick -e production -b $IP -p 3000

然后将您的[Service]块更改为类似这样的内容;确保设置为与保存[your username]目录的用户名相匹配:redmine_start.sh

[Service]
Type=simple
User=redmine
Group=redmine
ExecStart=/home/[your username]/redmine_start.sh

如果您遵循逻辑,如果的所有逻辑ExecStart都包含在内,redmine_start.sh那么您可以使用该 Bash 技巧获取 IP 地址,将其分配给变量,然后在那里启动 Redmine。脚本systemd只会管理何时/如何启动它。

使用 获取机器 IP 地址init.d

init.d用户参考,我使用 Ubuntu,当我需要在 Bash 或init.d启动脚本中获取当前工作系统 IP 地址时,我会运行如下命令:

ip=$(/sbin/ifconfig eth0 | awk '/inet addr/ {split ($2,A,":"); print A[2]}')

当然,您需要进行更改/sbin/ifconfig以匹配您系统上的位置ifconfig,然后还需要进行更改eth0以匹配您想要获取 IP 地址的网络接口。

但是一旦调整以匹配您的设置和需求,就可以成功获取接口的 IP 地址并将其分配给变量,然后可以像在脚本中ip一样访问该变量。$ip

答案2

也许这个构造可以工作。试试看:

[Service]
Type=simple
User=redmine
Group=redmine
PermissionsStartOnly=true
ExecStartPre=/bin/bash -c "/bin/systemctl set-environment ip=$(/sbin/ip -o -4 addr list eno16777736 | awk '{print $4}' | cut -d/ -f1)"
ExecStart=/usr/bin/ruby /home/redmine/redmine/bin/rails server webrick -e production -b ${ip} -p 3000

答案3

使用主机 IP 地址和EnvironmentFile

您可以使用以下方式将主机 IP 地址写入/etc/network-environment文件设置网络环境实用程序。然后您可以按照以下方式运行您的应用程序:

[Unit]
Requires=setup-network-environment.service
After=setup-network-environment.service

[Service]
EnvironmentFile=/etc/network-environment
ExecStart=/opt/bin/kubelet --hostname_override=${DEFAULT_IPV4}

来源:https://coreos.com/os/docs/latest/using-environment-variables-in-systemd-units.html

答案4

用于hostname -i获取您的(第一个)IP 地址并将其保存在 SystemD 的环境中。您可以使用 访问此变量${HOST_IP}

文档:

  • man hostname对于参数 -i 和 -I
  • man systemctl用于设置环境
  • man systemd.service对于 ExecStartPre

例子

[Service]
ExecStartPre=/bin/sh -c "systemctl set-environment HOST_IP=$(hostname -i)"

相关内容