I'm attempting to write a bash script that should be able to collect data from ttyS0 and put in a variable.

I need to talk with a device on the serial line, that is a module able to receive AT commands that I can send with echo > ttyS0 and capture the related answer in a variable. It's possible to do this without store the received answer in a variable (i.e. cat /dev/ttyS0 & ), but if I try to put this data in a variable (i.e. VAR=$(cat /dev/ttyS0 &) it doesn't work (in VAR I can not find anything after the answer of the module).

What I'm able to do "by hand" via gnome terminals (I'm working with a Ubuntu distribution) is the following:

  1. From a GNOME terminal that I call (A), I run (as root)

    # VAR=$(cat /dev/ttyS0) 

    This command doesn't return the root prompt #, because probably cat /dev/ttyS0 is running and waiting for input.

  2. From another GNOME terminal that I call (B), I run

    # echo -en "hello in VAR\r" > /dev/ttyS0 

    The hello in VAR string should go to /dev/ttyS0 and put by cat in VAR

  3. Then from (B):

    # killall cat

    From GNOME terminal (A) I can see that the prompt (#) returns;

  4. Finally from GNOME terminal (A):

    # echo "$VAR" 

    and I receive the hello in VAR string.

I tried to implement this via bash script in this way:


killall cat


echo "before VARcat_dev_ttyS0"
VAR=$(cat /dev/ttyS0)
echo "after VARcat_dev_ttyS0"
echo -en "hello in VAR\r" > /dev/ttyS0 
sleep 2
killall cat 
echo "content of VAR: $VAR"

exit 0

but the script stops after echo "before VARcat_dev_ttyS0" How can I implement what I want or what I'm able to do with two GNOME terminals?

  • 2
    This sounds an awful lot like an XY problem. What is your final objective here?
    – terdon
    Commented Feb 27, 2015 at 15:53
  • 1
    Please update your question to mention that you really are wanting to talk with a device on the serial line. This is important as it invalidates your stated assumptions and example working. Please also restate your requirements: are you wanting to talk to your serial device from your terminals, or create a testbed for some other undescribed program which doesn't require the serial device to be connected? Commented Feb 27, 2015 at 19:12
  • I roiama I did it. please see the new introduction of my requirement
    – lucat
    Commented Mar 1, 2015 at 22:01

1 Answer 1


It appears you're trying to use ttyS0 as a means to connect two processes. This won't work reliably since ttyS0 is the interface to a serial line (COM1: in Windows-speak).

On the other hand, it might be that information is missing from your question. If you really do have a device on your serial port, please make that clear.

What I believe you're looking for is a pipe. In the filesystem this looks much like a file, but allows data written to one side to be read from another. It's what is behind the scenes of the ubiquitous | operator, as in e.g. id | nl.

You can create a pipe with the mkfifo command, or mknod p if you insist.

Terminal #1

mkfifo /tmp/pipe        # Create the pipe
ls -l /tmp/pipe         # Notice the first character is 'p'

echo hello > /tmp/pipe  # Write to it
rm -f /tmp/pipe         # Remove the pipe

Terminal #2

cat /tmp/pipe           # Read from the other side of the pipe

You can extend the Terminal #2 code like this. Remember, though, that for each new read (actually open/read/close) on the pipe you need to give it fresh data.

read VAR </tmp/pipe    # Read one line from the pipe
VAR=(cat /tmp/pipe)    # Read from the pipe until EOF
  • In case of a single script, a background (e.g. &) is needed for the line that read/write the pipe (which ever you code first). This is not needed in case of two terminal.
    – Archemar
    Commented Feb 27, 2015 at 15:00
  • @roaima an terdon: I need ttyS0, because spots of data are coming to this port and I need to put them in a variable . however I'll try roaima suggestions
    – lucat
    Commented Feb 27, 2015 at 18:17

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .