2

Just started learning Linux Bash Shell Programming, and I just don't know if I understood it correctly. Looking at the sample program below:

#!/bin/bash
n=1
sumRSS=1000
sumSZ=2000

echo Before sumRSS=$sumRSS sumSZ=$sumSZ
ps -ly | while
read c1 c2 c3 c4 c5 c6 c7 c8 c9 c10
do
    if (( n>1 ))
    then
        echo n=$n rss=$sumRSS sz=$sumSZ
        ((sumRSS = sumRSS +  c8))
        ((sumSZ = sumSZ + c9))

    fi
    ((n++))
done

echo Sum of RSS = $sumRSS
echo Sum of SZ = $sumSZ

The output:

Before sumRSS=1000 sumSZ=2000
n=2 rss=1000 sz=2000
n=3 rss=2368 sz=29118
n=4 rss=3792 sz=55644
n=5 rss=4780 sz=82679
Sum of RSS = 1000
Sum of SZ = 2000

I don't know why the sum still goes back to RSS=1000 and SZ=2000. I actually was expecting RSS=4780 and SZ=82679.

I know I am missing something basic. I am learning bash by writing simple scripts.

codeforester
  • 39,467
  • 16
  • 112
  • 140
Mark Estrada
  • 9,013
  • 37
  • 119
  • 186
  • Did you write this sample code ? – George Vasiliou Jan 27 '17 at 07:55
  • @GeorgeVasiliou Nope, I got it from one of the online learning site where I am subscribed in. And just for my personal learning, I had edited and explore a little. I thought this was simple but I ran into this problem. – Mark Estrada Jan 27 '17 at 08:00
  • Welcome to Bash! Just a tip: You can include the option `set -xv` in your script (just after the `#!/bin/bash` line). This will enable verbose mode and will help you to see what is going on. Actually in your screen bash will inform you about the code that is going to be executed (step by step) and the values of the vars... Usefull debugging options. – George Vasiliou Jan 27 '17 at 08:06
  • By the way, in the learning site do they advise what is the expected output? I run this test and i get the same result as you. – George Vasiliou Jan 27 '17 at 08:07
  • Possible duplicate of [A variable modified inside a while loop is not remembered](https://stackoverflow.com/questions/16854280/a-variable-modified-inside-a-while-loop-is-not-remembered) – codeforester May 02 '18 at 02:32

2 Answers2

5

you should avoid the pipe as @linuxfan proposes. You can change your code to:

while read c1 c2 c3 c4 c5 c6 c7 c8 c9 c10
do
    ...
done < <(ps -ly)

this way your variables stay in the same scope.

Chris Maes
  • 35,025
  • 12
  • 111
  • 136
2

ps -ly | while

You notice the pipe character, "|", which creates two processes. As you know, the environment variables can not be exported from a process to its parent (only to its descendants). So the variables used in the process after the pipe, which is your while statement and its body, can be read and written, but once the process terminates, they get the value they had before.

Indeed, the above line of code creates two processes: one is ps, the output of which is passed to another process, which is another bash. Both processes receive a copy of the initial environment (i.e., the variables), and both processes can modify their copy. But the original process environment is never touched!