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

z9ju0rcb  于 2023-04-21  发布在  Shell
关注(0)|答案(1)|浏览(247)

我在一台Linux机器上运行2个nodJS服务器。为了让它们在我关闭控制台时也能运行,我用屏幕启动它们。这一切都很完美。只要我的Linux服务器提供商不做任何维护工作。然后我必须手动重新启动服务器。
我目前正在尝试加固我的NodeJS服务器,防止在我的Linux-Server-Provider的服务器维护后关闭。当Linux-Server再次备份时,节点服务器应该会自动重新启动。
根据Internet上的一些文章,我能够创建一个位于/etc/systemd/system/中的systemd服务。
当我运行systemctl list-units --all | grep my1984.service时,我可以看到在systemd中正确启用并加载了该服务
当我触发sudo systemctl status my1984.service时,我还可以看到它的状态。
这一切都很好。但现在是有趣的部分。
此服务调用shell脚本。这样做它只执行包含的echo命令。所有其他命令都被忽略。无论是在服务器重新启动后还是在我通过sudo systemctl start my1984.service手动启动此服务时运行它都无关紧要。但是当我用bash ./my1984.sh运行shell脚本本身时,脚本可以正常运行。这意味着所有echo命令以及所有其他命令都按预期得到处理。
我尝试将错误消息记录到错误文件中,但没有出现错误。似乎该服务只是忽略了除了echo之外的所有其他命令。无论我是用root还是用我的本地用户调用该服务,我都在sudoers.d中授予了一些额外的权限,以便能够使用systemctl。
以下是我的服务内容:

[Unit]
Description=My 1984 Service Test

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

[Install]
WantedBy=multi-user.target

这是我的shell脚本的内容

#!/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

正如我所说的,我的本地用户my 1984被赋予了一些sudo权限,以便能够结合sudo运行某些systemctl命令。
当我在本地使用bash-command调用脚本时,它可以正常工作,screen -ls在其列表中显示节点服务器。但是当my1984.service调用脚本时,只有echo-command被处理并将输出传递到文件中。screen -ls没有显示任何内容。在这种情况下,没有错误被写入error.log。
这种奇怪行为的原因是什么?
这里是一些关于我的Linux服务器等的技术信息

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
8mmmxcuj

8mmmxcuj1#

如果可以避免的话,启动一个双分叉进程(bash启动屏幕启动节点)是不好的做法。
最简单的解决方案是只创建两个服务,每个节点服务器一个。
我运行多个discord机器人和nodejs应用程序,我用完全相同的方式来做。
我知道,这不是你问的问题的解决方案,但它是你实际问题的解决方案:)
启动和停止服务器将使用systemctl完成,您可以使用journalctl观察这两个进程的控制台输出
要做到这一点,将你的nodejs脚本移动到一个更合适的地方。我喜欢使用/srv,但/opt也很好。
在本例中,我将使用/opt/servers
就用这样的东西作为你的服务文件
/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

对server 2执行相同的操作
你可以使用journalctl -u nodeserver1.service访问日志(读取journalctl的其他参数,如-f或-e)

相关问题