Quick AT Commands from the Linux Shell

Quick AT Commands from the Linux Shell

There are numerous tools available for Linux that allow the user to interact with Serial devices (usually known as Terminals or Serial Terminals), such as mincom or screen to name two, which are generally great at what they do, but experience shows they are not so good for scripting - here we look at an alternative approach.

Note: If you want a GUI Serial Terminal check out cutecom

The Problem

While these tools/applications do their job well, providing a Serial Terminal in a shell environment, they seem to fall short and running basic commands in an automated or scripted context. For example, minicom has a scripting mechanism but does not quit when finished, leading to numerous approaches to kill it once finished, most of which can probably be considered hacks.

Options

Other than the hacky scripts, another approach is to write an actual application that uses a library to talk to the Serial device - a very achievable alternative, but potentially a fair amount of work for the returns, depending on the use case or goal. It's also worth considering that the dependencies can be non trivial, for example the excellent NodeJS serialport library does require native code which depending on the target platform can be tedious or even tricky to install (though support for arm is better now).

Recently I was working on a project where I need to fire quick one-liner commands to a serial modem from either an application or script, and found a clean way to send a command and get a simple one-line response.

Socat

Socat is a command line based utility that establishes two bidirectional byte streams and transfers data between them. Because the streams can be constructed from a large set of different types of data sinks and sources (see address types), and because lots of address options may be applied to the streams, socat can be used for many different purposes.

From the socat manpage

Socat can do all-sorts of things including interacting with files, devices, over networks, and more.

In this instance we're simply going to use it to pipe stdin to a serial tty and let it log out the response.

An example (for retrieving Signal Quality from a Modem) is as follows:

echo AT+CSQ | socat - /dev/ttyUSB3,crnl

Running this against a test Modem gives:

❯ echo AT+CSQ | socat - /dev/ttyUSB3,crnl

OK

+CME ERROR: SIM not inserted

+CSQ: 99,99

OK

We can capture the response to a variable (note - the SIM was detected between example commands):

❯ TEST=$(echo AT+CSQ | socat - /dev/ttyUSB3,crnl)

❯ echo $TEST

+CSQ: 6,99

OK

That can be used in conventional shell scripting logic:

❯ if [[ "$TEST" == *"OK"* ]]; then echo 'Ok, apparently!'; fi 

Ok, apparently!

Conclusion

socat is very versatile utility, especially when working with a serial device. It can be easily incorporated into shell scripts to automate command execution without the need for (bloated) libraries or a higher-level language interpreter (such as Python or Node).

Note, when using the serial port direct it may be advisable to to set up beforehand with stty and setserial (YMMV):

# /bin/stty -F ${DEVICE} ${BAUDRATE}
# /bin/setserial ${DEVICE} low_latency