You are not logged in.

#1 2025-07-04 05:05:45

schard
Forum Moderator
From: Hannover
Registered: 2016-05-06
Posts: 2,306
Website

[SOLVED] bash: Read output line-by-line and return if pattern found

Obviously my bash-foo suffered over the years.
I am trying to read the output of a command line-by-line and return if a line contains a pattern.

Here's the MRE of what I'm trying to achieve. Feel free to replace $NEEDLE as needed.

#! /bin/bash

NEEDLE="Cannot find any crtc or sizes"

dmesg --follow | while IFS= read -r LINE; do
	if [[ "${LINE}" == *"${NEEDLE}"* ]]; then
		echo "Found: ${LINE}";
		exit 0;
	else
		echo "No match: ${LINE}";
	fi
done

The problem is, that this script does not exit when the pattern has been found.
I assume it's somehow because it's still waiting for the pipe from dmesg to close.
Is there a way to force the script to terminate, once the pattern has been found?

Last edited by schard (2025-07-05 11:32:51)


Inofficial first vice president of the Rust Evangelism Strike Force

Offline

#2 2025-07-04 06:05:56

seth
Member
Registered: 2012-09-03
Posts: 65,985

Re: [SOLVED] bash: Read output line-by-line and return if pattern found

You're exiting the subshell created by the pipe

while … do; … done < <(dmesg -W)
dmesg -W | grep --line-buffered -m1 "$NEEDLE" && exit

does not work?

Edit: missed a shift key wink

Last edited by seth (2025-07-04 06:06:22)

Online

#3 2025-07-04 09:14:06

qinohe
Member
From: Netherlands
Registered: 2012-06-20
Posts: 1,504

Re: [SOLVED] bash: Read output line-by-line and return if pattern found

The 'echo '"No match: ${LINE}"' is always run as long as there are 'No match' found before match 'Found'
You can leave the while loop with 'break'

Why not remove 'No match' from the equation.
I mean if everything is good, do you really need that message tongue

Edit:so I forget to paste the code...

#!/bin/bash

NEEDLE="RSDP"

sudo dmesg --follow | while IFS= read -r LINE; do
        if [[ "${LINE}" == *"${NEEDLE}"* ]]; then
                echo "Found: ${LINE}"
                break
        fi
done

To make it into a more useful tool replace 'NEEDLE' variable with:

printf '%s\n' "What line are you looking for"
read -r NEEDLE

Last edited by qinohe (2025-07-04 10:43:51)

Offline

#4 2025-07-04 14:37:24

dimich
Member
From: Kharkiv, Ukraine
Registered: 2009-11-03
Posts: 380

Re: [SOLVED] bash: Read output line-by-line and return if pattern found

Do you need to save matched line? If not, the script can be simplified to

dmesg --follow | grep -q "$NEEDLE"

or

dmesg --follow | sed "/$NEEDLE/q"

with all power of grep or sed options.

Offline

#5 2025-07-04 19:14:32

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,384
Website

Re: [SOLVED] bash: Read output line-by-line and return if pattern found

As a very different approach, you could use the -J flag for dmesg to get json output and pipe it to jq for search/filtering and formatting results' print out.


"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman

Offline

#6 2025-07-05 11:32:37

schard
Forum Moderator
From: Hannover
Registered: 2016-05-06
Posts: 2,306
Website

Re: [SOLVED] bash: Read output line-by-line and return if pattern found

Thank you all.

No, I don't actually need the output.
The script's purpose is to keep searching dmesg until a pattern is found and then terminate.
Its purpose is to operate in a systemd waiting service for certain kernel messages so that other services can be started after certain events have been logged.

@Seth
This works perfectly fine and solves my issue. Thank you.

Last edited by schard (2025-07-05 11:33:48)


Inofficial first vice president of the Rust Evangelism Strike Force

Offline

Board footer

Powered by FluxBB