导致导入命令通过服务运行时失败的原因是什么

导致导入命令通过服务运行时失败的原因是什么

我们的 System V 服务运行一个运行 import 命令的守护进程。通过sudo service myservicestart 运行我们的服务似乎可以启动服务,但当需要截取屏幕截图时,import 不起作用。截取屏幕截图的唯一方法是使用 start 启动服务/etc/init.d/myservice。之后,我们可以使用 import 命令截取屏幕截图。

有任何想法吗?

答案1

除了“这取决于环境”,即 GNU / Linux 发行版之外,对您的问题没有直接的答案。

在我介绍半相关的细节之前,您应该知道,不起作用的原因sudo service import-image-service是因为 import 命令没有足够的环境信息来知道在哪里以及如何截取屏幕截图。阅读 man sudo 揭示:

 DESCRIPTION
   sudo allows a permitted user to execute a command as the superuser or
   another user, as specified by the security policy.

这有点神秘,了解这个“安全政策”很有趣,但可能不是你最喜欢的活动之一。我向你保证,这意味着以 sudo 开头的命令在隔离环境中运行

相反,/etc/init.d/myservice之所以有效,是因为 environment-setup-policy 采取了一些步骤来配置一些合理的默认值,例如export DISPLAY=:0.0。您必须调查正在使用的发行版的复杂性,才能弄清楚如何正确地通知服务有关 X 服务器的存在。同时,您可以尝试sudo -E service myservice

  -E      The -E (preserve environment) option indicates to the secu‐
       rity policy that the user wishes to preserve their existing
       environment variables.  The security policy may return an
       error if the -E option is specified and the user does not
       have permission to preserve the environment.

一些背景知识

警告:本节内容为半事实且有历史偏见

GNU / Linux 系统中的服务在不同发行版之间表现得有些随意。主要区别在于环境设置在服务运行之前。这取决于几个因素,其中最重要的是:

  • 初始化系统
    • 普通 System V init + posix shell(Slackware、Debian)
    • OpenRC(Gentoo)
    • 新贵 (Ubuntu)
    • systemd(许多最近的发行版)
  • 分布环境设置策略*
  • 特定初始化脚本的详细信息

Debian、Slackware 和 Gentoo (OpenRC) 使用了一种类似方法,其中 /etc/init.d/ 服务是独立的脚本,可选地从 /etc/default/servicename、/etc/conf.d/servicename 和类似文件中获取其他信息。脚本可能依赖或不依赖特定于发行版的 init 函数,例如 /lib/lsb/init-functions 或 /lib64/rc/sh/functions.sh。这些附加 shell 库可以从其他特定于发行版的来源获取信息(设置环境)。

Ubuntu(Upstart)和 systemd 采用“完全”不同的方法,其中每个服务都有一个配置文件,然后由 init 系统完成所有神奇的工作。

要完全理解发生了什么,必须阅读并理解 init 系统和正在使用的分布的怪癖。

* 初始化环境变量和启动服务的过程。

答案2

Linux 旧系统 V 的手册页中对此进行了非常清楚的解释service第一句话

服务运行 System V init 脚本在尽可能可预测的环境中,删除大多数环境变量并将当前工作目录设置为/。

您认为该命令如何知道在哪里找到您的 X 服务器?当然 image是环境变量。DISPLAY

不要依赖这样的概念:服务运行在具有控制终端、DISPLAY环境变量等的交互式登录环境中。事实并非如此。如果你根据这些假设设计了一项服务,那么你就设计错了,而且你设计的东西甚至无法为你工作现在,更不用说如果您使用不同的 init 系统(例如 systemd、upstart、nosh、runit 等)它也能起作用,所有这些都确保服务在启动/关闭时不受交互式 shell 的环境变量(和其他进程状态)的任意值的影响。

相关内容