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を使用して起動されたプログラムから呼び出すとスクリプトは実際には実行されますが、chatコマンドは実行されません。 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

この場合、スクリプトは Home Assistant というプログラムから呼び出されます。ホームアシスタントはsystemd.serviceスクリプトから始まります。 systemd.serviceを実行しているのと同じユーザーとして端末でHome Assistantを起動すると、上記の内容は表示されず、テキストメッセージが送信されます。

systemctlを使用して起動された他のプログラムから同じスクリプトを呼び出すと、同じエラーが発生します。

答え1

これはsystemdとは何の関係もなく、systemctlプログラムの基本的な正しい使用に関連するすべてですchat

chat通常、PPPデーモンにバンドルされているプログラムです。これLinux PPP FAQ、Al Longyearで管理、少なくとも1996年以降:

17.6。私は逃げたchat。ローカル端末をモデムとして使用したいようですが、モデムと通信できません。モデム名はどのように指定しますかchat

chat「フィルタ」というプログラムクラスに属します。つまり、標準入力から読み込み、内部的にいくつかの処理を行い、標準出力に書き込みます。

したがって、実際に実行してchatモデムと通信するには、標準入出力がモデムにリダイレクトされるように<I / Oリダイレクト演算子を使用する必要があります。>

しかし、、使用するchat場合pppd[...]

何を見てあなた次のためです:

チャットタイムアウト 1 "" "AT+CMGF=1" "OK" > /dev/ttyUSB0

chat標準出力はシリアルデバイスに接続されていますが、標準入力を含むシェルスクリプトの標準入力に接続されているプログラムを実行しています。対話型ログインセッションでシェルスクリプトを実行すると、これが端末になり、デーモンの標準入力になります(ほぼ確実です)。いいえ端末文字デバイスである) デーモンでシェルスクリプトを実行するとき。

chatシリアルデバイスとチャットしないのは当然です。chatデーモンでシェルスクリプトを実行するときに端末デバイスと通信しないと文句を言うのは当然です。

だから正しく使用されましたchatLinux PPP FAQ説明する。標準入力と出力を通信するデバイスと同じデバイスにします。

chat正しいデバイスに接続して使い始めると、シリアルデバイスのオンとオフをchat切り替えるためにこれらの呼び出しをすべて実行したくありません。繰り返しますが、これはsystemdまたはデーモンとは無関係であり、共有標準の入出力ファイル記述を持つシェルで複数の連続コマンドを実行するメカニズムの簡単な練習です。

あるいは、実際に実行する操作に応じて、シェルスクリプト全体をこのように実行して、最初にスクリプトを呼び出すすべてのプログラムからスクリプト全体の標準入力と出力を適切なデバイスにリダイレクトすることもできます。 (この場合、最良の結果-sを得るにはオプションを使用してくださいchat。)

答え2

(制御)端末を持たないSystemDプロセスが問題を引き起こす可能性があります。

より良い解決策は、JdeBPの答えで説明されているように正しいアプローチを使用することですが、chat一般的なケースでは...

スクリプトに次のコードを追加できます。

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

これは/dev/tty(制御)端末で開きます。

答え3

まあ、私はチャットの本当の目的を理解していませんでした。私は誰かのブログからいくつかのコードをコピーしました。あまりにも多くのLinuxプログラムの問題は、マニュアルページが学ぶのに数週間かかるという用語でいっぱいになることが多いことです。一般ユーザーには適していません。

私は現在、スクリプトにgammuというプログラムを使用しています。これで、システムサービスから呼び出されても正常に動作します。

答え4

なぜそんなに神秘的な方法を使うのですか?今日は、ModemManagerでmmcliを使用してテキストメッセージを読んで送信してください。バラよりhttps://sigquit.wordpress.com/2012/09/14/sms-goodies-in-modemmanager/

関連情報