无法从使用 systemd 启动的程序访问 USB 设备

无法从使用 systemd 启动的程序访问 USB 设备

我有以下脚本来使用 GSM USB 调制解调器发送 SMS 消息:

#!/bin/bash

env > /home/hans/systemenv.txt
#touch /home/homeassistant/pipo2.txt
read count < /home/homeassistant/.homeassistant/smsCounter.txt

stty -F /dev/ttyUSB0 9600 min 100 time 2 -hupcl brkint ignpar -opost -onlcr -isig -icanon -echo

chat TIMEOUT 1 "" "AT+CMGF=1" "OK" > /dev/ttyUSB0
chat TIMEOUT 1 "" "AT+CMGS=\"0123456789\"" "OK" > /dev/ttyUSB0
chat TIMEOUT 1 "" "$1" "OK" > /dev/ttyUSB0
chat TIMEOUT 1 "" "^Z" "OK" > /dev/ttyUSB0

#sleep 2

#chat TIMEOUT 1 "" "AT+CMGS=\"0987654321\"" "OK" > /dev/ttyUSB0
#chat TIMEOUT 1 "" "$1" "OK" > /dev/ttyUSB0
#chat TIMEOUT 1 "" "^Z" "OK" > /dev/ttyUSB0

let 'count++'
echo $count > /home/homeassistant/.homeassistant/smsCounter.txt

当从命令行调用时,该脚本工作正常,但是当从任何使用 systemd 启动的程序调用它时,脚本实际上会运行,但聊天命令不会被执行。当从 systemd 服务中运行的程序调用脚本时,运行 sudo Journalctl -f -xe 会显示以下内容:

Oct 08 13:37:37 homeassistant chat[2641]: Can't get terminal parameters: Inappropriate ioctl for device
Oct 08 13:37:37 homeassistant chat[2642]: Can't get terminal parameters: Inappropriate ioctl for device
Oct 08 13:37:37 homeassistant chat[2643]: Can't get terminal parameters: Inappropriate ioctl for device
Oct 08 13:37:37 homeassistant chat[2644]: Can't get terminal parameters: Inappropriate ioctl for device

在本例中,该脚本是从一个名为“家庭助理”的程序调用的。家庭助理是从 systemd.service 脚本启动的。如果我从终端启动家庭助理,作为运行 systemd.service 的同一用户,上面的内容不会显示,并且会发送短信。

从使用 systemctl 启动的任何其他程序调用相同的脚本都会导致相同的错误。

答案1

这与 systemd 无关,systemctl也与程序的基本正确使用有关chat

chat是一个通常与 PPP 守护程序捆绑在一起的程序,这已在Linux PPP 常见问题解答,由阿尔·朗伊尔维护,至少从 1996 年开始:

17.6。我跑了chat。它似乎想使用本地终端作为调制解调器,但它不与调制解调器通信。如何指定调制解调器名称chat

chat属于一类称为“过滤器”的程序。也就是说,它从标准输入读取,在内部进行一些处理,然后写入标准输出。

因此,如果您确实只想运行chat并让它与调制解调器通信,那么您需要使用 I/O 重定向运算符<>以便将标准输入和输出重定向到调制解调器。

然而,如果您使用的chatpppd,请[...]

看看什么是做:

聊天超时 1 "" "AT+CMGF=1" "确定" > /dev/ttyUSB0

您正在运行chat,其标准输出连接到串行设备,但其标准输入连接到任何封闭的 shell 脚本的标准输入。当您从交互式登录会话运行 shell 脚本时,这将是终端,以及守护程序的标准输入,无论是什么(几乎肯定会不是是终端字符设备),当您从守护程序运行 shell 脚本时。

难怪不chat与串行设备聊天。难怪chat当您从守护进程运行 shell 脚本时,它会抱怨它甚至不与终端设备通信。

所以正确使用chat,就像Linux PPP 常见问题解答说。使其标准输入和输出为同一设备,即您尝试与之通信的设备。

chat一旦您开始使用chat连接到正确的设备,您可能不想通过所有这些多次调用来打开和关闭串行设备。同样,这与 systemd 或守护进程无关,而是从具有共享标准标准输入和输出文件描述的 shell 运行多个连续命令的机制的简单练习。

或者,事实上,根据它的作用,甚至以这种方式运行整个 shell 脚本,将整个脚本的标准输入和输出重定向到首先调用该脚本的任何程序中的适当设备。 (在这种情况下,请使用-s选项以chat获得最佳结果。)

答案2

该问题可能是由 SystemD 进程没有(控制)终端引起的。

更好的解决方案是按照 JdeBP 的答案解释使用chat正确的方法,但对于一般情况......

您可以将此代码添加到脚本中:

tty &>/dev/null || exec </dev/tty

这将/dev/tty作为(控制)终端打开。

答案3

好吧,我没有意识到聊天的真正目的。我只是从某人的博客复制了一些代码。如此多的 Linux 程序的问题在于,手册页中常常充斥着需要数周时间才能学习的术语。不适合普通用户。

我现在在我的脚本中使用一个名为 gammu 的程序。现在它工作得很好,即使它是从 systemd 服务调用的。

答案4

你为什么要使用如此神秘的方式来做到这一点?如今,只需使用 ModemManager 中的 mmcli 来读取和发送短信即可。看https://sigquit.wordpress.com/2012/09/14/sms-goodies-in-modemmanager/

相关内容