2

I have the filling simplified script on Mac OS X 10.12 :

#!/usr/bin/env bash

echo "=> BASH_VERSION = $BASH_VERSION"
function testForLoopMac {
local file
for file
do
    echo File=$file
done | egrep "$file"
}

function testForLoopMacBis {
local file
for file
do
    echo File=$file
done | egrep "$file|OK"
}

testForLoopMac $@

testForLoopMacBis $@

But the result when I run is :

$ testForLoopMac.sh example.pdf 
=> BASH_VERSION = 3.2.57(1)-release
File=example.pdf
egrep: empty (sub)expression

On Debian/Ubuntu Linux, the result is :

$ testForLoopMac.sh example.md 
=> BASH_VERSION = 4.3.30(1)-release
File=example.md
File=example.md

Edit : With bash4 on Mac OSX 10.12 :

I changed the shebang to #!/usr/bin/env bash4 and the result is the same :

$ testForLoopMac.sh example.md 
=> BASH_VERSION = 4.4.12(1)-release
File=example.md
egrep: empty (sub)expression

Edit: Thanks to you guys I understand the behavior difference on Linux or BSD egrep is because that at the time of the egrep execution the variable can be empty.

I'm going the use therefore, the following regExp :

egrep "File=|OK"

Thanks again :)

5
  • Can you add the BASH_VERSION both from macOS and from Linux? – nohillside May 5 '17 at 11:14
  • 1
    I think the script is too simplified to show your real intent. Are the arguments to the script supposed to be regular expressions? – 0942v8653 May 5 '17 at 11:44
  • @patrix I update the Question with the bash version information because comments only use mini-Markdown formatting which is a pain in the @~~ – SebMa May 6 '17 at 12:56
  • For what it's worth editing the question to include such information is the preferred thing to do rather than adding it in the comments since comments are ephemeral. – grg May 6 '17 at 13:13
  • @0942v8653 the script is ideal to show how execution on macOS and Linux differ. Which is all the question is about :-) – nohillside May 6 '17 at 14:13
2

The shell expands the subexpression $file on the right hand side of the pipe before the variable has any value. So in both functions egrep is actually called with the empty string in place of $file. The first function doesn't throw an error because an empty pattern is a valid parameter for egrep both on macOS and on Linux. In the second fucntion the difference comes into play because the empty subexpression causes BSD egrep (the one used on macOS) to throw an error.

Example:

echo foo | egrep "|foo"
egrep: empty (sub)expression

as another example with $file having no value

echo foo | egrep "$file|foo"
egrep: empty (sub)expression

So, as a workaround in your function use:

egrep -e "$file" -e 'OK'

I have no idea why you are using egrep when you are looking for fixed strings.

9
  • The expansion is done by bash not by egrep, so I struggle a bit to understand your first sentence. – nohillside May 6 '17 at 18:06
  • @patrix Yep, you're right. Will edit. – fd0 May 6 '17 at 18:39
  • Thanks. I still wonder why it works on Linux though – nohillside May 6 '17 at 19:10
  • @patrix It's the difference between BSD grep and GNU grep. GNU grep doesn't complain about empty subexpressions for one thing. – fd0 May 6 '17 at 19:52
  • @patrix Maybe, on linux, the variable is not distroyed when the loop is finished. – SebMa May 7 '17 at 14:11

You must log in to answer this question.

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