C. Pappy
C. Pappy

Reputation: 747

Simple conditional unexpectedly fails in bash if statement

I've spent an embarrassingly long time trying to understand why the second conditional in the "foo" script below fails but the first one succeeds.

Please note:

Thanks in advance for any help.

Session: (Running on a Centos7 host):

>ls
bar  foo
>cat foo
#!/bin/bash

s1="bar foo"
s2="bar foo"
s3=`ls`

echo -n $s1 | hexdump -C
echo -n $s2 | hexdump -C
echo -n $s3 | hexdump -C

if [ "$s1" = "$s2" ]; then  # True
    echo s1 = s2
fi

if [ "$s1" = "$s3" ]; then  # NOT true! Why?
    echo s1 = s3
fi

>foo
00000000  62 61 72 20 66 6f 6f                              |bar foo|
00000007
00000000  62 61 72 20 66 6f 6f                              |bar foo|
00000007
00000000  62 61 72 20 66 6f 6f                              |bar foo|
00000007
s1 = s2
>

Upvotes: 0

Views: 38

Answers (2)

Jonathan Leffler
Jonathan Leffler

Reputation: 755006

Your demo would be more convincing with echo -n "$s1" etc. That would show that there's a newline in the middle of s3 where there's a space in s1 and s2. The echo without the double quotes mangles the newline into a space (and generally each sequence of one or more white space characters in the string into a single space).

Given:

#!/bin/bash

s1="bar foo"
s2="bar foo"
s3=`ls`

echo -n "$s1" | hexdump -C
echo -n "$s2" | hexdump -C
echo -n "$s3" | hexdump -C

if [ "$s1" = "$s2" ]; then  # True
    echo s1 = s2
fi

if [ "$s1" = "$s3" ]; then  # NOT true because s3 contains a newline!
    echo s1 = s3
fi

I get:

$ sh foo
00000000  2d 6e 20 62 61 72 20 66  6f 6f 0a                 |-n bar foo.|
0000000b
00000000  2d 6e 20 62 61 72 20 66  6f 6f 0a                 |-n bar foo.|
0000000b
00000000  2d 6e 20 62 61 72 0a 66  6f 6f 0a                 |-n bar.foo.|
0000000b
s1 = s2
$ bash foo
00000000  62 61 72 20 66 6f 6f                              |bar foo|
00000007
00000000  62 61 72 20 66 6f 6f                              |bar foo|
00000007
00000000  62 61 72 0a 66 6f 6f                              |bar.foo|
00000007
s1 = s2
$

Upvotes: 2

choroba
choroba

Reputation: 242333

Quote the variables when echoing.

echo -n "$s3" | hexdump -C

You'll see a newline between the file names, as ls uses -1 when the output is redirected.

Upvotes: 4

Related Questions