4

Problem: I have dmesg | grep ttyUSB command that has the following output:

[    7.648896] usb 1-2: GSM modem (1-port) converter now attached to ttyUSB0
[    7.649091] usb 1-2: GSM modem (1-port) converter now attached to ttyUSB1
[    7.649502] usb 1-2: GSM modem (1-port) converter now attached to ttyUSB2
[17406.327030] option1 ttyUSB0: GSM modem (1-port) converter now disconnected from ttyUSB0
[17406.329670] option1 ttyUSB1: GSM modem (1-port) converter now disconnected from ttyUSB1
[17406.334036] option1 ttyUSB2: GSM modem (1-port) converter now disconnected from ttyUSB2
[90128.405694] usb 1-4: GSM modem (1-port) converter now attached to ttyUSB0
[90128.405987] usb 1-4: GSM modem (1-port) converter now attached to ttyUSB1
[90128.406295] usb 1-4: GSM modem (1-port) converter now attached to ttyUSB2
[90132.905458] usb 1-2: GSM modem (1-port) converter now attached to ttyUSB3
[90132.905791] usb 1-2: GSM modem (1-port) converter now attached to ttyUSB4
[90132.906541] usb 1-2: GSM modem (1-port) converter now attached to ttyUSB5
[90148.661532] usb 1-1: GSM modem (1-port) converter now attached to ttyUSB6
[90148.661828] usb 1-1: GSM modem (1-port) converter now attached to ttyUSB7
[90148.662440] usb 1-1: GSM modem (1-port) converter now attached to ttyUSB8

need to redirect this output to a text file, I am using the following command for this:

dmesg | grep ttyUSB > test.txt

Everything works fine, but I need only list the available ports. I wish the text file output to be like this:

ttyUSB0 
ttyUSB1 
ttyUSB2 
ttyUSB3

How can I do this?

2 Answers 2

6

Just use this command:

dmesg | egrep -o "ttyUSB[0-9]+" | sort -u > test.txt

It will match and return the ttyUSB patterns.

From man grep:

   -o, --only-matching
          Print only the matched (non-empty) parts of a matching line,
          with each such part on a separate output line.
3
  • Thanks, I'm still newbie in Linux. The output contains some duplicate ports, it is possible to remove the duplicate entries or need to do this in my programming language? Apr 24, 2014 at 9:30
  • I've updated my answer accordingly. just using sort -u. Apr 24, 2014 at 9:32
  • -u being the uniq flag, of course.
    – Rob
    Apr 24, 2014 at 14:14
3

I would argue the problem is slightly harder than being advertised. Just parsing dmesg for instances of ttyUSB* won't let you know if it's currently available. It might have just been disconnected.

The following works this out by looking at the current status. It does this by looking for to ... and from ... instances and only uses the ones where it was a to ttyUSB* at the end of the line.

dmesg | tac | awk '$NF~/ttyUSB[0-9]+/ && !a[$NF]++ && $(NF-1)=="to" {print $NF}'

To quickly explain:

  • tac reverses the input so we're dealing with the most recent first
  • $NF ~ /ttyUSB[0-9]+/ is a regex that checks the last field is a ttyUSB*
  • !a[$NF]++ checks that we haven't seen this field before
  • $(NF-1) == "to" filters on the penultimate field to make sure we're dealing with to ... lines.

To test this I've simply taken your output and have removed the second attach. In my example ttyUSB2 was connected, then disconnected and never reconnected. It shouldn't be available.

$ cat testdmesg 
[    7.648896] usb 1-2: GSM modem (1-port) converter now attached to ttyUSB0
[    7.649091] usb 1-2: GSM modem (1-port) converter now attached to ttyUSB1
[    7.649502] usb 1-2: GSM modem (1-port) converter now attached to ttyUSB2
[17406.327030] option1 ttyUSB0: GSM modem (1-port) converter now disconnected from ttyUSB0
[17406.329670] option1 ttyUSB1: GSM modem (1-port) converter now disconnected from ttyUSB1
[17406.334036] option1 ttyUSB2: GSM modem (1-port) converter now disconnected from ttyUSB2
[90128.405694] usb 1-4: GSM modem (1-port) converter now attached to ttyUSB0
[90128.405987] usb 1-4: GSM modem (1-port) converter now attached to ttyUSB1
[90132.905458] usb 1-2: GSM modem (1-port) converter now attached to ttyUSB3
[90132.905791] usb 1-2: GSM modem (1-port) converter now attached to ttyUSB4
[90132.906541] usb 1-2: GSM modem (1-port) converter now attached to ttyUSB5
[90148.661532] usb 1-1: GSM modem (1-port) converter now attached to ttyUSB6
[90148.661828] usb 1-1: GSM modem (1-port) converter now attached to ttyUSB7
[90148.662440] usb 1-1: GSM modem (1-port) converter now attached to ttyUSB8

$ tac testdmesg | awk '$NF~/ttyUSB[0-9]+/ && !a[$NF]++ && $(NF-1)=="to" {print $NF}'
ttyUSB8
ttyUSB7
ttyUSB6
ttyUSB5
ttyUSB4
ttyUSB3
ttyUSB1
ttyUSB0

And of course you can pass that through sort if you want. You shouldn't need to uniq (or sort -u) it though as awk should have handled dupes already.

2
  • I am impressed with this, was actually creating a solution in Python to test if the ports are connected or not. Thank you both for the answers. Apr 24, 2014 at 14:30
  • @RenatoTavares if that's your goal, I recommend you to use udev calls like this one stackoverflow.com/a/12939648/792066
    – Braiam
    Apr 24, 2014 at 15:49

You must log in to answer this question.

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