You are not logged in.

#1 2018-06-14 09:32:12

Linux2Brain
Member
Registered: 2018-03-05
Posts: 11

[solved] shell script: output of grep into variable

Hi,

I'm trying to run a little test script which looks in dmesg if my dvb-device is already up.
My main problem is how to put the output of grep (also if empty) into a variable and check that,
I seem to do something wrong, but I can't figure it out.

Here is my test script:

#!/bin/bash

dvb_device = $(dmesg|grep  "DVB\: registering adapter 0 frontend 0")

while   [ "x$dvb_device"  == "x" ]
do
        echo "waiting for DVB device..."
        sleep 3
done

echo "device is up! :)" 

I want the output of dmesg|grep ... assigned to the variable dvb_device, but that doesn't work,
I get the output "dvb_device: command not found".

How can I do that ?

Last edited by Linux2Brain (2018-06-14 09:50:58)

Offline

#2 2018-06-14 09:47:25

WorMzy
Forum Moderator
From: Scotland
Registered: 2010-06-16
Posts: 8,146
Website

Re: [solved] shell script: output of grep into variable

Remove the whitespace around the equals sign.

EDIT: This is an odd way of doing what you're trying to accomplish though. Just use grep's exit value (0 = match found, 1 = no matches).

Last edited by WorMzy (2018-06-14 09:49:34)


Sakura:-
Mobo: MSI X299 TOMAHAWK ARCTIC // Processor: Intel Core i7-7820X 3.6GHz // GFX: nVidia GeForce GTX 970 // RAM: 32GB (4x 8GB) Corsair DDR4 (@ 3000MHz) // Storage: 1x 3TB HDD, 5x 1TB HDD, 2x 120GB SSD, 1x 275GB M2 SSD

Making lemonade from lemons since 2015.

Offline

#3 2018-06-14 09:50:30

Linux2Brain
Member
Registered: 2018-03-05
Posts: 11

Re: [solved] shell script: output of grep into variable

OMG!

Thank you very much! smile

I didn't think that this is an issue, coming from python, java and C# I'm used to these white spaces due to readability. smile

Offline

#4 2018-06-14 10:03:05

progandy
Member
Registered: 2012-05-17
Posts: 3,015

Re: [solved] shell script: output of grep into variable

By the way, the example doesn't work. You set a variable only once at the beginning and never again. Then you try to wait for a change which will never occur. Or you might have already unplugged your dvb device and dmesg still contains this line. Then you detect the device even if it is missing.

Last edited by progandy (2018-06-14 10:06:13)


| alias CUTF='LANG=en_XX.UTF-8@POSIX ' |

Offline

#5 2018-06-14 10:25:57

ayekat
Member
Registered: 2011-01-17
Posts: 1,253
Website

Re: [solved] shell script: output of grep into variable

There is a logic error, though: this executes dmesg | grep only once, and stores the result in a variable; it then loops until the variable (magically) is no longer empty (which will never happen).
EDIT: ninja'd by progandy

while ! dmesg | grep 'DVB\: registering adapter 0 frontend 0' >/dev/null; do
    echo 'Waiting ...'
    sleep 3
done

But this is a rather wasteful use of `dmesg`. I've tried a naive approach like this:

# doesn't work!
dmesg -w | while read -r line; do
    case "$line" in
        (*'DVB\: registering adapter 0 frontend 0'*) break ;;
        (*) echo 'Waiting ...'; sleep 3 ;;
    esac
done

However, `dmesg -w` keeps running even if the part after the pipe has exited. If this worked, one could (1) get rid of the multiple calls to `dmesg` and (2) get rid of grep entirely. Maybe some more experienced shell scripter can shed some light onto this? smile

Last edited by ayekat (2018-06-14 10:27:56)

Offline

#6 2018-06-14 11:12:50

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 19,750
Website

Re: [solved] shell script: output of grep into variable

ayekat, dmesg should quit, and it does here.  But that "sleep 3" really really shouldn't be there as it sleeps 3 seconds between reading each line.  Given my current dmesg size, it would take an hour for it to reach the end, and if messages come in faster than every 3 seconds, it will never catch up.  The sleep does nothing useful there anyways as `read` already blocks waiting for new input:

#!/bin/bash

echo "waiting for DVB device..."
dmesg -w | while read -r line; do
        [[ "$line" =~ 'whatever you want to match' ]] && break
done
echo "device is up! :)" 

Last edited by Trilby (2018-06-14 11:14:17)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#7 2018-06-14 11:46:32

progandy
Member
Registered: 2012-05-17
Posts: 3,015

Re: [solved] shell script: output of grep into variable

If this script tries to detect a usb dvb device, then it is error prone. This detects the device as present even if it has been removed again after plugging it in. I'd prefer to check for an entry in sysfs, maybe in /sys/class/dvb?


| alias CUTF='LANG=en_XX.UTF-8@POSIX ' |

Offline

#8 2018-06-14 11:48:52

ayekat
Member
Registered: 2011-01-17
Posts: 1,253
Website

Re: [solved] shell script: output of grep into variable

Oops, yeah, the sleep is unnecessary.

I noticed something really odd, though... if I match something very early (in my case within the first 86 lines of dmesg output), it exits properly.
However, if I match something on line 87 or later, it stays blocked.
Maybe there is some buffering limit or I-don't-really-know-what that changes the behaviour of the pipe (or more likely dmesg) in my case, and it happens to be somewhere around lines 86, 87 in my case:

#!/bin/bash

lno=0
dmesg -w | while read -r line; do
	lno=$((lno + 1))
	echo "$lno $line"
	[[ "$line" =~ .*0x155655000.* ]] && break   # this matches something on line 87, and it remains blocked
done

Last edited by ayekat (2018-06-14 12:07:49)

Offline

#9 2018-06-14 11:50:22

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 19,750
Website

Re: [solved] shell script: output of grep into variable

Or perhaps `lsusb -d $vendor`

@ayekat, ah yes, blocking waiting on more input is very different from what I thought you first suggested: that dmesg kept running after the script exited.  I just replicated the blocking on waiting for more input from dmesg, I'm not sure what exactly that is about yet.

(edit: removed some suspicions that didn't pan out)

Right now it seems to block if the loop breaks (due to a match found) and only when that match is over some number of lines into the input.  A match early breaks properly, a failure to match anything progresses to the end and exits properly, but a break near the end, blocks.  I suspect this is anything that is past the end of the piper buffer size, but I'm not sure why.

Last edited by Trilby (2018-06-14 12:10:14)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

Board footer

Powered by FluxBB