Bentoy13
Bentoy13

Reputation: 4974

Bash - bad assignment value to variable

I want to do a very simple script: just want to find the newest version of a program, say svn, on my computer. I want to load the result into a variable, say mysvn

So I make this script:


#!/bin/sh

mysvn="foobar"
best_ver=0
which -a svn | while read p
do
    version=$("$p" --version | grep 'version ' | grep -oE '[0-9.]+' | head -1)
    if [[ "$version" > "$best_ver" ]]
    then
        best_ver=$version
        mysvn="$p"
    fi
    echo $mysvn
done

echo $mysvn

Very simple in fact ... but it does not work under rxvt (my pseudo-linux terminal), version 2.7.10, running under XP: the final output string is foobar.

Does anybody know why I have this problem?

I have been writing some scripts for the past few months, it is the first time I encounter such a behaviour.

Note: I know how to make it work, with a few changes (just put the main lines into $() )

Upvotes: 4

Views: 3003

Answers (2)

Gordon Davisson
Gordon Davisson

Reputation: 126048

The reason this occurs is that the while loop is part of a pipeline, and (at least in bash) any shell commands in a pipeline always get executed in a subshell. When you set mysvn inside the loop, it gets set in the subshell; when the loop ends, the subshell exits and this value is lost. The parent shell's value of mysvn never gets changed. See BashFAQ #024 and this previous question.

The standard solution in bash is to use process substitution rather than a pipeline:

while
...
done < <(which -a svn)

But note that this is a bash-only feature, and you must use #!/bin/bash as your shebang for this to work.

Upvotes: 2

Miguel
Miguel

Reputation: 566

Here on Ubuntu:

:~$ which -a svn | while read p
> do
>   version=$("$p" --version | grep 'version ' | grep -oE '[0-9.]+' | head -1)
>   echo $version
> done
.

so, your version is ., not very nice.

I tried this, and I think it's what you're looking for:

:~$ which -a svn | while read p
> do
>   version=$("$p" --version | grep -oE '[0-9.]+' | head -1)
>   echo $version
> done
1.7.5

Upvotes: 0

Related Questions