I have the following script to send SMS messages with a GSM usb modem:


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

The script works fine when called from the command line, but when it is called from any program that was started with systemd, the script actually runs, but the chat commands do not get executed. Running sudo journalctl -f -xe, shows the following when the script is called from a program running in a systemd service:

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

In this case, the script was called from a program called home assistant. Home assistant was started from a systemd.service script. If I start home assistant from the terminal, as the same user that the systemd.service was running as, the above do not show and the sms gets sent.

Calling the same script from any other program that was started with systemctl results in the same error.

  • What happens if you run the script through nohup? Oct 8 '17 at 13:55
  • What is your actual questio, something that ends withh a "?" ...? Oct 8 '17 at 13:57
  • There is no change in behavior when starting with nohup. Oct 8 '17 at 14:25
  • The question is: How can I prevent the errors from happening when running the script from a program that has been started with systemctl, so that the sms message gets sent? Oct 8 '17 at 14:26

This is nothing to do with systemd or systemctl and everything to do with basic correct use of the chat program.

chat is a program usually bundled with the PPP dæmon, and this has been answered in the Linux PPP FAQ, maintained by Al Longyear, since at least 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 […]

Look at what you are doing:

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

You are running chat with its standard output connected to a serial device, but its standard input connected to whatever the enclosing shell script's standard input happens to be. That will be the terminal when you run the shell script from your interactive login session, and the dæmon's standard input, whatever that is (which almost certainly will not be a terminal character device), when you run the shell script from a dæmon.

It is no wonder that chat isn't chatting to the serial device. It is no wonder that chat is complaining that it isn't even talking to a terminal device when you run the shell script from a dæmon.

So use chat properly, as the Linux PPP FAQ says. Make both its standard input and output the same device, the device that you are trying to talk to.

You might well not be wanting to open and close the serial device over all of those multiple invocations of chat, once you start using chat connected to the right device. That, again, is nothing to do with systemd or dæmons, but is a simple exercise in the mechanism of running multiple successive commands from the shell having shared standard standard input and output file descriptions.

Or, indeed, depending from what it does, even running the entire shell script that way, redirecting standard input and output of the entire script to the appropriate device in whatever program is invoking that script in the first place. (Use the -s option to chat for best results in that case.)


The problem is probably caused by SystemD processes not having a (controlling) terminal.

The better solution is to use chat right as JdeBP's answer explained but for the general case...

You may add this code to the script:

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

This opens /dev/tty as a (controlling) terminal.


Ok, I did not realize the real purpose of chat. I just copied some of the code from someone's blog. The problem with so many Linux programs is that often the man pages are flooded with terms that take weeks to learn. Not suitable for the normal user.

I am now using a program called gammu in my script. Now it works just fine, even if it is called from a systemd service.


Why are you using such an arcane way of doing this ? nowadays it is a simple as using mmcli from ModemManager to read and send SMS. See https://sigquit.wordpress.com/2012/09/14/sms-goodies-in-modemmanager/

  • I have abandoned trying to use chat. I am now using gammu. It's easier to use than mmcli. Oct 10 '17 at 18:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.