[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Segfault in Bash

From: Greg Wooledge
Subject: Re: Segfault in Bash
Date: Tue, 14 Jul 2020 07:49:07 -0400
User-agent: Mutt/1.10.1 (2018-07-13)

On Tue, Jul 14, 2020 at 06:32:44AM -0400, Jeffrey Walton wrote:
> $ ./audit-libs.sh /home/jwalton/tmp/ok2delete/lib
> ./audit-libs.sh: line 17: 22929 Segmentation fault      (core dumped)
> $(echo "$file" | grep -E "*.so$")

This grep regular expression is not valid.  The * symbol in a regular
expression means "0 or more of the previous thing", so you can never
begin a regular expression with a * character.

Also, the . character in a regex means "any one character", not a
literal dot.

If for some reason you actually wanted to grep for lines that end
with the string ".so", it would be:

grep '\.so$'

However, the *use* of grep here is also incorrect.

> My code is broken at the moment. I know I am the cause of Bash's
> crash. But I feel like Bash should not segfault.
> IFS="" find "$dir" -name '*.so' -print | while read -r file
> do
>     if ! $(echo "$file" | grep -E "*.so$"); then continue; fi
>     echo "library: $file"
> done

I don't even understand what the grep is supposed to be *doing* here.
You already know that each file processed by that check ends with .so
because of the find command that you used.  You could simply remove
the "if" line altogether.

IFS isn't actually doing anything, either.  It only applies to the
find command, not the other half of the pipeline.  And of course, find
(an external command) will just ignore it.

What you really want is simply:

find "$dir" -type f -name '*.so' -exec printf 'library: %s\n' {} +

If your code is "just an example" (bashphorism 9), and you actually
wanted to do MORE than print each filename, and thus you really did
want a bash loop to process each file within the script, then you
need to change a few things.  Your existing loop will blow up on any
filenames containing newlines.  Also, because you used a pipeline,
the loop runs in a subshell, so you can't set any variables and have
them survive -- this may or may not be a problem, and we can't know
because we don't know what the actual goal of the script is.

A proper while loop to process the pathnames emitted by grep would look
something like:

while IFS= read -r -d '' f; do
  : secret stuff here
done < <(find "$dir" -type f -name '*.so' -print0)

reply via email to

[Prev in Thread] Current Thread [Next in Thread]