0

I have used a loop to create a set of screens using Bash that are connected to a set of serial ports:

for i in $(ls /dev/ttyACM*)
do
    screen -S ${i##*/} -L -d -m $i
done

Subsequently, I want to send reset commands to all of these screens repeatedly until they are all closed (some of the devices require several resets in order to reboot). For this I need a list of the active screen session names.

Unfortunately, a command like for j in $(screen -ls); do echo $j; done returns this:

There
are
screens
on:
33097.ttyACM6
(17.05.2021
18.53.46)
(Detached)
33085.ttyACM0
(17.05.2021
18.53.46)
(Detached)
2
Sockets
in
/run/screen/S-keir.finlowbates.

What I'd like is a command like that, which returns:

ttyACM6
ttyACM0

Then I'd be able to run:

for i in $(<<magic stuff here>>)
    screen -S ${i##*/} -X stuff 'reset^M'
done

until there are no more screens left.

Can anyone help me with the <<magic stuff here>>?

1
  • Have you tried ps -ef|grep screen? You can get the tty they are running there
    – YoMismo
    May 17, 2021 at 18:05

2 Answers 2

1

screen -ls prints out in the format

There are screens on:
    screen_name    (Status)
X Sockets in /path/to/screen/socket/dir

Your specific output probably looks something like this:

There are screens on:
    33097.ttyACM6    (17.05.2021 18.53.46)   (Detached)
    33085.ttyACM0    (17.05.2021 18.53.46)   (Detached)
2 Sockets in /run/screen/S-keir.finlowbates.

So when the for loop you wrote is iterating over those values, it is just echoing each item separated by whitespace.

Assuming that all of your screens will match the format you gave and have a tty associated then the simplest way to get that information would be to just run screen -ls | grep "tty"| awk '{print $1}' | cut -d. -f 2.

screen -ls returns the results shown above, grep tty returns only the lines with tty in them, awk {print $1} prints the first column in that line, and cut -d. -f2 sets the delimiter to be a . and returns the field 2, which in this case would be the tty values.

For your example this would return:

ttyACM6
ttyACM0
1
  • 2
    1. The space in the quoted "tty " prevents this from working at all. (tty is a fixed string and doesn't need to be quoted, anyway) 2. The lack of single quotes around the awk script also prevents it from working. 3. If you're using awk, you don't need grep - awk can do pattern matching. 4. awk can split on more than just spaces, so there's no need for cut, either. 5. putting that all together: screen -ls | awk -F'[ .]+' '/tty/ {print $3}'
    – cas
    May 18, 2021 at 1:14
1

Although screen doesn't return a neatly formated result, it turns out you can query the Linux file system to get the required information:

ls /var/run/screen/S-${USER}

This returns the PID and the screen session name, e.g. 443653.ttyACM6 443818.ttyACM6. Although you can use substitution to remove everything up to and including the dot, it turns out that you can reattach to a screen session with the whole PID.sessionName:

for i in $(ls /var/run/screen/S-${USER})
  do
    screen -r ${i} -X stuff 'reset^M'
  done

You must log in to answer this question.

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