2

My script doesn't work. It doesn't remember changed values of variables. I made following script:

#!/bin/bash

kon_p=100
kon_m="nothing"

cat /etc/list | grep -v '#' | while read machine priority ;
do  
    if [ $priority -le $kon_p ]
    then
        kon_p=$priority 
        kon_m=$machine

    fi  

done

 echo priority machine is $kon_m with priority $kon_p

and the result is:

  priority machine is nothing with priority 100

why no changes?

file "list" is following

         Debian_pokus   1
         debian_2       2
         debian_3       3

anyone Can you help me please?

3
  • 4
    The variables are set in the subshell opened by the while, so the main process does not have access to them. Commented Dec 10, 2013 at 12:59
  • 3
    See mywiki.wooledge.org/BashFAQ/024 for a thorough explanation, including workarounds. Commented Dec 10, 2013 at 13:04
  • You deserve an award: partmaps.org/era/unix/award.html Commented Dec 10, 2013 at 13:21

2 Answers 2

2

There is a FAQ on this exact question on Greycat wiki (a bash reference).

What's wrong

Read more about process substitution.

Solution

#!/bin/bash

kon_p=100
kon_m="nothing"

while read machine priority ; do  
    if (( $priority < $kon_p )); then
        kon_p=$priority 
        kon_m=$machine
    fi  
done < <(grep -v '#' /etc/list)

printf "priority machine is %s with priority %s\n" "$kon_m" $kon_p
Sign up to request clarification or add additional context in comments.

Comments

0

The subshell was doing you in, this should work:

#!/bin/bash

kon_p=100
kon_m="nothing"

IFS=$'\n'
for line in $(cat /etc/list | grep -v '#')
do  
    IFS=' ' read -ra values <<< "${line}"
    if [ ${values[1]} -le $kon_p ]
    then
        echo "doing it."
        kon_p=${values[1]} 
        kon_m=${values[0]}
    fi  
done

echo priority machine is $kon_m with priority $kon_p

3 Comments

don't do this can of loop for … in $(), it behaves inconsistently depending on the source. Also read about word splitting
also see my response there is plenty of links to support it.
BTW, you can affect kon_p and kon_m directly in the read. Something like: read -r kon_m kon_p leftover <<< "$line"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.