您缺少尝试运行的脚本的完整路径。

您缺少尝试运行的脚本的完整路径。

我在启动一些为运行 ArchLinux 环境(在 VM 中运行)而创建的应用程序时遇到了问题。

我有一些可执行文件(用 C++ 和 Python 编写),必须在 VM(Oracle)启动 Arch Linux 时启动。

我已经为此编写了一个 shell 脚本(我已经测试过并且还赋予了所需的权限),用于启动这两个进程(它们在会话中永远保持活动状态),并且我还指定了一个必须启动 Shell 的服务(在 ../System/.. 中)但即使命令systemctl enable/start/Status显示一切正常,我也看不到进程(使用 ps 命令)。

我不确定,但我可以想象服务启动了该进程,但最终它们以某种方式被杀死,即使该进程带有 shell 脚本&

奇怪的是,我用来挂载文件夹的相同例程是可以接受的,并且没问题,但不知何故(可能是缺乏经验)我无法成功自动启动这两个过程。

这是我的 shell 脚本:

 #!/bin/sh

/bin/python3  /myPath/firstexe &
/bin/python3 /myPath/secondexe &

的结果:

systemctl Status myservice.service

是:

...
Process:ExecStart=.../myshell (Code=exited, Status=0/SUCCESS)
...

你能帮我解决这个问题吗?

答案1

我不确定,但我可以想象服务启动了该进程,但最终它们以某种方式被杀死,即使 shell 脚本中的进程带有 &。

不,那是为什么他们被杀了。

标准 systemd 服务可以包含任意数量的进程,但始终需要只有一个“主”进程。当该进程运行时,Systemd 认为服务“正在运行”,当该进程退出时,则认为服务“已停止”。一旦服务停止(无论是自行停止还是您手动停止systemctl stop),systemd 就会终止由其启动的所有“剩余”进程。

这意味着:

  1. 每个 systemd .service 只能启动一个守护进程 - 在您的情况下,当有两个独立的长时间运行的进程时,它们应该作为两个单独的 .service 文件进行管理。

    (然而,该服务随时都有各种子进程运行 - 例如工作进程 - 无论 Type= 或其他服务设置如何。

  2. 您不应该通过中间 shell 脚本启动守护进程。Systemd 最终会跟踪脚本而不是守护进程本身,因此脚本一完成,它就会认为服务已“退出”。

  3. 如果进程尝试自行“守护进程”或“进入后台”,则需要使用选项告诉 systemd 预期结果Type=forking。但是,就您而言,不需要这样做。(默认为 Type=simple。)

  4. 然而,如果过程没有就其本身而言,“守护进程”、强制使用它&是多余的 —— 服务已经存在于“后台”,可以这么说,systemd 可以同样好地处理守护进程和非守护进程服务。

(最后,对于只需要执行快速任务并且实际上没有守护进程的“服务”有一个例外 - 您可以对这些服务使用 Type=oneshot。)

答案2

您缺少尝试运行的脚本的完整路径。

在我看来,您应该将其更改firstexesecondexe这些文件的完整路径。

进入它们所在的目录,输入pwd,这将为您提供工作目录的路径。将其放在 firstexe andsecondexe like this; using/full/path/to/` 之前,例如:

/full/path/to/firstexe

和:

/full/path/to/secondexe

我还建议您将 shell 脚本“shebang”更改如下:

#!/bin/sh

对此:

#!/bin/bash -l

Bash 是更常见且限制较少的 shell 脚本,它-l会将环境变量传递给您的脚本。这实际上不是您问题的核心,但我建议一般情况下对 shell 脚本都使用它。

总之,我建议使用此版本的脚本;只需更改/full/path/to/为这些脚本的实际完整路径:

#!/bin/bash -l

/bin/python3 /full/path/to/firstexe &
/bin/python3 /full/path/to/secondexe &

相关内容