为什么我的systemd服务执行我的Shell脚本,但除了echo之外不执行任何命令?

huangapple go评论54阅读模式
英文:

why does my systemd service execute my shell script but not execute any command except echo?

问题

I run 2 Node.js servers on a Linux machine. In order to keep them running even when I close the console, I start them with the "screen" command. This all works perfectly, as long as my Linux server provider doesn't perform maintenance work. Then I have to restart the servers manually.

I am currently trying to ensure that my Node.js servers automatically restart after server maintenance by creating a systemd service located in /etc/systemd/system/.

The service is correctly enabled and loaded in systemd when I run systemctl list-units --all | grep my1984.service. I can also see its status with sudo systemctl status my1984.service.

However, the service only executes the echo commands in the shell script it calls. All other commands are being ignored, whether the service runs after a server reboot or when I start it manually with sudo systemctl start my1984.service. But when I run the shell script itself with bash ./my1984.sh, it works as expected, processing all commands.

I've tried logging error messages, but no errors appear. It seems the service ignores all commands except echo, regardless of whether I run it with root or my local user (with sudo rights for systemctl).

Here is the content of my service:

[Unit]
Description=My 1984 Service Test

[Service]
ExecStart=/bin/bash /home/my1984/scripts/my1984.sh

[Install]
WantedBy=multi-user.target

And here is the content of my shell script:

#!/bin/bash

echo $(date -u) "executing my1984.sh." >> /home/my1984/scripts/scripts.log
screen -ls >> scripts.log
screen -S NODE-Server1 -d -m node /home/my1984/node-server1/bin/www 2>> error.log
echo $(date -u) "starting screen node @ node-server1." >> /home/my1984/scripts/scripts.log

screen -S NODE-Server2 -d -m node /home/my1984/node-server2/bin/www 2>> error.log
echo $(date -u) "starting screen node @ node-server2." >> /home/my1984/scripts/scripts.log

echo $(date -u) "my1984.sh has been executed." >> /home/my1984/scripts/scripts.log

I've granted my local user (my1984) sudo rights for certain systemctl commands.

When I call the script locally with the bash command, it works properly, and screen -ls shows the node servers. But when the my1984.service calls the script, only the echo commands produce output, and screen -ls is empty. No errors are written to error.log.

What could be causing this behavior?

英文:

I run 2 nodJS servers on a Linux-Machine.
In order to keep them running even when I close the console I start them with screen.
This all works perfectly. As long as my Linux-Server-provider doesn't do any maintenance work. Then I have to restart the servers manually.

I am currently trying to harden my NodeJS-Servers against being down after a server maintenance of my Linux-Server-Provider. The node servers are supposed to restart automatically when the Linux-Server is back up again.

Following some of the many articles on the Internet I was able to create a systemd Service which is located in /etc/systemd/system/.

I can see the service being correctly enabled and loaded in systemd when I run systemctl list-units --all | grep my1984.service

I also can see its status when I fire sudo systemctl status my1984.service.

This all works pretty fine. But now comes the interesting part of it.

This service calls a shell script. And doing so it only executes the contained echo commands. All the other commands are being ignored. And it doesn't matter whether it is run after a server reboot or when I start this service manually via sudo systemctl start my1984.service. But when I run the shell script itself with bash ./my1984.sh the script gets run properly, meaning that all echo commands as well as all the other commands are getting processed as expected.

I tried to log error messages into an error file but no errors appear. It seems that the service simply ignores all the other commands but echo. And it does not matter whether I call the service with root or with my local user that I granted some extra right in sudoers.d in order to being able to use systemctl.

Here is the content of my service:

[Unit]
Description=My 1984 Service Test

[Service]
ExecStart=/bin/bash /home/my1984/scripts/my1984.sh

[Install]
WantedBy=multi-user.target

This is the content of my shell script

#!/bin/bash

echo $(date -u) "executing my1984.sh." >>  /home/my1984/scripts/scripts.log
screen -ls >> scripts.log
screen -S NODE-Server 1  -d -m  node /home/my1984/node-server1/bin/www 2>> error.log
echo $(date -u) "starting screen node @ node-server1." >> /home/my1984/scripts/scripts.log

screen -S NODE-Server 2 -d -m  node /home/my1984/node-server2/bin/www 2>> error.log
echo $(date -u) "starting screen node @ node-server2." >> /home/my1984/scripts/scripts.log

echo $(date -u) "my1984.sh has been executed." >> /home/my1984/scripts/scripts.log

As I said, my local user my1984 has been given some sudo rights in order to be able to run certain systemctl commands in combination with sudo.

When I call the script locally with the bash-command it works properly and screen -ls shows the node servers in its list. But when the my1984.service calls the script only the echo-commands are being processed and deliver output into the file. screen -ls shows no content. No errors are being written to the error.log in this case.

What can be the cause of this strange behaviour?


Here is some technical information about my Linux Server and so on

Linux
NAME="Ubuntu"
VERSION="18.04.4 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.4 LTS"
VERSION_ID="18.04"


Screen
Screen version 4.06.02 (GNU) 23-Oct-17

Node
v17.9.1

答案1

得分: 1

It is bad practice to start a double forking process (bash starting screen starting node) if it can be avoided.

Easiest solution would be to just create two services, one for each node server.

I run multiple discord bots and nodejs applications, and I am doing it this exact same way.

I know, this is not the solution for you asked question, but it is the solution for your actual problem 为什么我的systemd服务执行我的Shell脚本,但除了echo之外不执行任何命令?

Starting and stopping the servers would be done with systemctl, and you can observe the console output of both processes with journalctl


To accomplish this, move your nodejs scripts to a more appropriate place. I like to use /srv but /opt would be fine as well.

For this example I will use /opt/servers

Just use something like this as your service file
/etc/systemd/system/noderserver1.service:

[Unit] 
Description=1984 Server 1 

[Service] 
ExecStart=/usr/bin/node /opt/servers/node-server1/bin/www 

[Install] 
WantedBy=multi-user.target 

do the same for server2

you would access the logs with journalctl -u nodeserver1.service (read up on other parameters like -f or -e of journalctl)

英文:

It is bad practice to start a double forking process (bash starting screen starting node) if it can be avoided.

Easiest solution would be to just create two services, one for each node server.

I run multiple discord bots and nodejs applications, and I am doing it this exact same way.

I know, this is not the solution for you asked question, but it is the solution for your actual problem 为什么我的systemd服务执行我的Shell脚本,但除了echo之外不执行任何命令?

Starting and stopping the servers would be done with systemctl, and you can observe the console output of both processes with journalctl


To accomplish this, move your nodejs scripts to a more approriate place. I like to use /srv but /opt would be fine as well.

For this example I will use /opt/servers

Just use something like this as your service file<br>
/etc/systemd/system/noderserver1.service:

[Unit]
Description=1984 Server 1

[Service]
ExecStart=/usr/bin/node /opt/servers/node-server1/bin/www

[Install]
WantedBy=multi-user.target

do the same for server2

you would access the logs with journalctl -u nodeserver1.service (read up on other parameters like -f or -e of journalctl)

huangapple
  • 本文由 发表于 2023年4月20日 05:18:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76058887.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定