Можем ли мы записать pid в файл, который хранится в systemd? - proUbuntu
0 голосов
/

У меня есть скрипт для запуска Java-приложения во время загрузки.

[Unit]
Description=test Background

[Service]
ExecStart=/bin/bash -c "/usr/bin/java -jar /var/www/tset.com/*.jar"
Type=simple
WorkingDirectory=/var/www/test.com

[Install]
WantedBy=multi-user.target

Можем ли мы отредактировать это, чтобы записать pid в файл в определенном месте?

В качестве примера

ExecStart=/bin/bash -c "/usr/bin/java -jar /var/www/test.com/*.jar | echo $! > ${RUNNING_PID}"

Ответы [ 3 ]

2 голосов
/

Вы должны иметь возможность запускать Java напрямую, а не запускать оболочку bash, которая запускает Java. Если вы сделаете это, вы можете запустить команду systemctl show , чтобы получить PID

systemctl show -p MainPID <your service name>

при условии, конечно, что ваше Java-приложение не создает больше процессов.

Если файл имени вашей службы оканчивается на .service, вы можете опустить суффикс .service из <your service name>

Если вы запустите скрипт bash, вы получите pid оболочки bash, которая выполняет ваш процесс Java.

1 голос
/

Я бы подошел к этой проблеме следующим образом:

ExecStart=/bin/bash -c 'echo $$ > /var/run/tset.pid; exec /usr/bin/java -jar /var/www/tset.com/*.jar'

Есть пара вещей, которые требуют внимания:

  • вы пытаетесь написать .pid файл, содержащий PID процесса, а в Linux «де-факто» местоположение - поместить его в /var/run

  • Оператор > предназначен для перенаправления stdout из echo, который будет содержимым $$ или PID оболочки.

  • Почему PID оболочки? Ну, это потому, что следующая вещь, которую мы используем, это команда exec, которая заменит процесс оболочки на ваше java-приложение. То, что было PID 1234, представляющим оболочку, теперь будет 1234, представляющим Java-приложение.

Такой подход, хотя и кажется запутанным, на самом деле более уместен:

  • мы знаем PID вместо того, чтобы использовать ps или pgrep, чтобы найти его, нам не нужно применять сложный синтаксический анализ, и у нас нет проблем, если уже запущено несколько экземпляров приложения (которое не должно в случае, если вы используете сервис systemd для его запуска, но нет никакой опасности в учете и такой возможности)
  • и exec ресурсы не будут потрачены впустую для запуска нескольких процессов. Когда у вас есть что-то вроде bash -c '/usr/bin/java -jar myapp.jar & pgrep -f myapp.jar > /var/run/myapp.pid ', это 3 процесса. В приведенной выше команде предлагается - у нас один процесс заменяет другой.

Конечно, это всего лишь пример. Отрегулируйте, насколько это необходимо для вашего случая, и /var/run/tset.pid выбрано здесь просто в качестве примера - наименование зависит от вас, а также от местоположения файла, хотя я бы рекомендовал использовать /var/run для согласованности с другими приложениями.

Примечание:

Часть | echo $! > ${RUNNING_PID}" не подходит по крайней мере по одной причине: ${RUNNING_PID} - это переменная, однако она нигде не объявлена, поэтому она будет заменена на plank в оболочке. | бессмысленно - stdout Java-приложения подключено к stdin из echo, что в случае, если вы хотите, чтобы вывод приложения, отправленного в другое приложение, был уместным, но echo не читает stdin - т.е. вот оно бессмысленно.

Конечно, если само приложение (то есть приложение java) разветвляется - то есть создает - другой процесс, $$ не сильно поможет, хотя, чтобы быть совершенно справедливым, если приложение действительно создает несколько разветвлений, оно, вероятно, должно быть задачей самого приложения по созданию и управлению файлом .pid и сообщению основного процесса pid.

0 голосов
/

systemd оставляет pid вашего процесса в окружении, поэтому вы можете использовать его в своем скрипте:

    [Unit]

    [Service]
    ExecStart=/home/blah/my-process.sh
    ExecStop=/bin/kill -HUP $MAINPID
    PIDFile=/home/blah/blah.pid

    [Install]
...