não pode acessar o dispositivo USB de um programa iniciado com o systemd

0

Eu tenho o seguinte script para enviar mensagens SMS com um modem USB:

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

O script funciona bem quando chamado a partir da linha de comando, mas quando é chamado de qualquer programa iniciado com o systemd, o script é executado, mas os comandos de chat não são executados. Executando sudo journalctl -f -xe, mostra o seguinte quando o script é chamado de um programa em execução em um serviço systemd:

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

Neste caso, o script foi chamado de um programa chamado home assistant. O assistente inicial foi iniciado a partir de um script systemd.service. Se eu iniciar o assistente doméstico do terminal, como o mesmo usuário que o systemd.service estava executando, o acima não será mostrado e o SMS será enviado.

Chamar o mesmo script de qualquer outro programa que foi iniciado com o systemctl resulta no mesmo erro.

    
por user2879815 08.10.2017 / 15:44

4 respostas

0

Ok, eu não percebi o real propósito do chat. Acabei de copiar um pouco do código do blog de alguém. O problema com tantos programas Linux é que muitas vezes as páginas do manual são inundadas com termos que levam semanas para serem aprendidos. Não é adequado para o usuário normal.

Agora estou usando um programa chamado gammu no meu script. Agora funciona muito bem, mesmo que seja chamado a partir de um serviço systemd.

    
por 08.10.2017 / 16:55
1

Isso não tem nada a ver com systemd ou systemctl e tudo a ver com o uso correto básico do programa chat .

chat é um programa geralmente empacotado com o servidor PPP, e isso foi respondido em o Linux PPP FAQ , mantido pela Al Longyear , desde pelo menos 1996:

17.6. I ran chat. It seems to want to use the local terminal as the modem and it does not talk to the modem. How do I specify the modem name to chat?

chat is in a class of programs called a 'filter'. That is, it reads from the standard input, does some processing internally, and writes to the standard output.

So, if you really want to just run chat and have it talk to a modem then you need to use the I/O redirection operators < and > so that the standard input and output are redirected to the modem.

However, if you are using chat with pppd, please […]

Veja o que você está fazendo:

chat TIMEOUT 1 "" "AT+CMGF=1" "OK" > /dev/ttyUSB0

Você está executando chat com sua saída padrão conectada a um dispositivo serial, mas sua entrada padrão está conectada ao que quer que seja a entrada padrão do script de shell. Esse será o terminal quando você executar o script de shell a partir de sua sessão de login e a entrada padrão do daemon, seja lá o que for (o que certamente não será um dispositivo de terminal), quando você executar o script script de shell de um daemon.

Não é de admirar que chat não esteja conversando com o dispositivo serial. Não é de admirar que chat esteja reclamando que nem está falando com um dispositivo de terminal quando você executa o script de shell de um daemon.

Portanto, use chat corretamente, como diz o Linux PPP FAQ . Faça a entrada e a saída padrão do mesmo dispositivo, o dispositivo com o qual você está tentando conversar.

Você pode não querer abrir e fechar o dispositivo serial em todas as várias chamadas de chat , depois de começar a usar chat conectado ao dispositivo correto. Isso, novamente, não tem nada a ver com systemd ou dæmons, mas é um exercício simples no mecanismo de execução de vários comandos sucessivos a partir do shell que possui descrições de arquivo de entrada e saída padrão padrão compartilhadas.

Ou, na verdade, dependendo do que ele faz, até mesmo executar todo o script de shell dessa maneira, redirecionando a entrada e a saída padrão de todo o script para o dispositivo apropriado em qualquer programa que esteja invocando o script em primeiro lugar. (Use a opção -s para chat para obter melhores resultados nesse caso.)

    
por 08.10.2017 / 16:33
0

O problema provavelmente é causado por processos SystemD que não possuem um terminal (controlador).

A melhor solução é usar chat como a resposta do JdeBP explicou, mas para o caso geral ...

Você pode adicionar este código ao script:

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

Isso abre /dev/tty como um terminal (controlador).

    
por 08.10.2017 / 16:42
0

Por que você está usando uma maneira tão misteriosa de fazer isso? hoje em dia é simples usar o mmcli do ModemManager para ler e enviar SMS. Consulte o link

    
por 09.10.2017 / 18:53