如何从服务在终端窗口中启动脚本

如何从服务在终端窗口中启动脚本

我有两个脚本,它们一起允许我通过串行方式接听和接听电话。第一个脚本是我想在后台作为服务运行的,它会检查是否有 RING 信号,如果有,则打开一个终端窗口并运行第二个脚本。

它们都使用python3,第一个脚本是:

while True:
if (ser.inWaiting() > 0):
    x = ser.readline()
    if (x == b'RING\r\r\n'):
        os.system("gnome-terminal -- python3 /home/user/answer.py")
        exit()

第二部分主要内容为:

    os.system("clear")
    print("Incoming Call")
    PU = input("Press Enter To Pick Up")
    send_at('ATA' + ';','OK',1)
    os.system("clear")
    print("ON CALL")
    HU = input("Press Enter To Hang Up")
    send_at("AT+CHUP\r\n" + ';','OK',1)
    os.system("clear")
    print('Call Ended')
    time.sleep(3)
    os.system("clear")
    os.system("gnome-terminal -- python3 /home/user/ring.py")
    os.system("exit")

如果我在打开的终端中运行第一个程序“python3 ring.py”,它可以正常工作,但会让我有一个不断打开的终端。

我想要的是将 Ring.py 作为服务或后台进程运行,并在调用 Answer.py 时启动它。

我尝试使用 .service 文件,启用并启动它,htop 显示它正在运行 Ring.py,但它不会在终端窗口中启动 Answer.py。没有错误代码,只是没有显示。

这是服务文件:

[Unit]
Description=Detect Incoming Calls

[Service]
Type=simple
User='my username'
ExecStart= /usr/bin/python3 /home/user/Ring.py
Restart=always

[Install]
WantedBy=multi-user.target

我怎样才能让它按我想要的方式工作?或者我做错了什么?

答案1

gnome-terminal是一个用户 GUI 应用程序,它首先需要启动并运行显示服务器用户会话,然后启动它的服务将需要设置某些环境变量和/或授予适当的身份验证/权限。

您可以在系统服务中指定这些环境变量,例如,通过设置显示服务器的地址,但这可能会发生变化,您可能需要再次设置它,并且启动 GUI 用户应用程序不仅仅是systemd指定这些变量,所以不推荐这样做,在我看来,用户服务才是可行的方法。

因此,您需要将您的服务设置为用户服务,以便默认与您的用户会话环境进行交互,因为环境变量$DISPLAY将由用户服务自动继承。

要做到这一点你需要第一的,将您的单位/服务文件放在用户主目录中的/usr/lib/systemd/user/或 下。~/.config/systemd/user/

然后systemd无需重新启动即可通知它,如下所示:

systemctl --user daemon-reload

然后,启用并启动和管理它国旗--user没有 sudo像这样:

systemctl --user enable unit-name

和:

systemctl --user start unit-name

从现在开始你将总是需要使用该--user标志来管理它...例如:

systemctl --user status unit-name

或者:

systemctl --user restart unit-name

或者:

systemctl --user stop unit-name

注意

您不需要为用户服务指定用户/组,因为它将默认以您当前登录的用户身份运行。

如果您的脚本没有设置状态报告,您可能还需要进行更改Restart=always以避免运行脚本的多个实例。Restart=on-failure

您可能还想更改WantedBy=multi-user.target[Install]部分WantedBy=default.target或类似的图形用户目标。

相关内容