7

Мне нужно получить 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

3 ответа3

8

Получение имени хоста машины с помощью 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, и когда мне нужно получить текущий IP-адрес рабочей системы в скрипте запуска Bash или init.d я запускаю что-то вроде этого:

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

Конечно, вам нужно изменить /sbin/ifconfig чтобы он соответствовал расположению ifconfig в вашей системе, а затем также изменить eth0 чтобы соответствовать сетевому интерфейсу, для которого вы хотите получить IP-адрес.

Но однажды настроенный в соответствии с вашими настройками и потребностями, он успешно получает IP-адрес интерфейса и назначает его переменной ip которой затем можно получить доступ как $ip в вашем скрипте.

5

Может быть, эта конструкция будет работать. Попытайся:

[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
5

Используйте IP-адреса хоста и EnvironmentFile

Вы можете записать IP-адреса своего хоста в файл /etc/network-environment с помощью утилиты setup-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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .