我需要获取机器的 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
并分配$IP
值123.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 和 -Iman systemctl
用于设置环境man systemd.service
对于 ExecStartPre
例子
[Service]
ExecStartPre=/bin/sh -c "systemctl set-environment HOST_IP=$(hostname -i)"