while loops and variables under bash


Login or Register for Dates, Times and to Reply

 
Thread Tools Search this Thread
# 1  
while loops and variables under bash

Hi,

This is probably going to be very simple but i came across something i can't quite explain. Here is the situation: i have a list of files, which i'd like to process one by one (get the size, make some tests, whatever) and generate some statistics using different variables.

Something similar to this:

Code:
u=0
ls|while read f; do
#until [ $u -gt 5 ]; do
#for f in `ls `; do
echo inside u=$u
let "u+=1"
done

echo outside u=$u

And here are the results (there are 3 files in the current directory):

Quote:
inside u=0
inside u=1
inside u=2
outside u=0
So basically the variable u appears to get re-initialised somehow.

Using until or a classic for loop u keeps its value after the loop is executed, like this:

Quote:
inside u=0
inside u=1
inside u=2
inside u=3
inside u=4
inside u=5
outside u=6
So what's the deal ? That's under bash. Ksh gives similar results to the other loops.
# 2  
It's not the different kinds of loops that are doing it -- it's the pipe that does it. By putting your while loop behind a pipe, you are executing it inside a subshell. Values get changed in the subshell, not the main one, and don't get copied back.

ksh organizes pipes in a different order than other Bourne shells. The innermost loop runs in the current shell while the outermost loop runs in the subshell. This is a KSH-only feature.

Depending on your goal, there are various ways to circumvent or just plain avoid this. This is a useless use of ls * for instance -- a situation where you might as well be using the * operator instead of the external ls utility.

Code:
for X in *
do
        let "u+=1"
done

The 'for' loop overcomes this by putting ls in backticks, which runs it first, and sets the value in a variable. But this is not recommended as it will be confused by filenames with spaces in them.
This User Gave Thanks to Corona688 For This Post:
# 3  
Aha.. makes all sense now. Thanks for explaining and that nice link
# 4  
Quote:
Originally Posted by Corona688
By putting your while loop behind a pipe, you are executing it inside a subshell.
@Corona688: I too thought the same, and tried to check this by printing the pid of shell before entering while loop and inside while loop. Pid's are same. If its invoking a sub-shell it should print the pid of the sub-shell inside while loop, right?

Code:
#! /bin/bash
u=0
echo "before while, pid = $$"
ls | while read x
do
    echo "inside while, pid = $$"
    ((u++))
done

Code:
# bash --version
GNU bash, version 3.1.17(1)-release (i686-redhat-linux-gnu)
# ./test.sh
before while, pid = 6435
inside while, pid = 6435
inside while, pid = 6435
inside while, pid = 6435

Any idea what's happening here?
# 5  
@balajesuri: from man bash:
Quote:
Special parameters
[..]
$: Expands to the process ID of the shell. In a () subshell, it expands to the process ID of the current shell, not the subshell.
Quote:
Each command in a pipeline is executed as a separate process (i.e., in a subshell).
This User Gave Thanks to Scrutinizer For This Post:
# 6  
@Scrutinizer: Yes, you're right. How could I miss that!
Login or Register for Dates, Times and to Reply

Previous Thread | Next Thread
Thread Tools Search this Thread
Search this Thread:
Advanced Search

Test Your Knowledge in Science: Gadgets
Difficulty: Easy
Microphones can be used not only to pick up sound, but also to project sound similar to a speaker.
True or False?

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Correlation Between 3 Different Loops using Bash

I have 3 loops that I use to determine the permission level of AWS user accounts. This array lists the AWS policy ARN (Amazon Resource Name): for ((policy_index=0;policy_index<${#aws_managed_policies};++policy_index)); do aws_policy_arn="${aws_managed_policies}" ... (1 Reply)
Discussion started by: bluethundr
1 Replies

2. Shell Programming and Scripting

Pipe 2 bash loops together

What is the proper way to run two bash loops in the same command? The two below loops run separately, the problem is when I pipe them I get an error that the file used for the second loop does not exist. I am not sure how to wait for the first loop to complete and then start the second. Thank... (10 Replies)
Discussion started by: cmccabe
10 Replies

3. Shell Programming and Scripting

Unset variables in shell when it running two different loops

I have a script to start/stop/restart the tomcat application. When we run the script first time i.e stop/start it set all env variables(DISTRIB_ID,NAME,TOMCAT_CFG,....etc),but when we restart the tomcat it is running in the same shell.....I need to set the variables when i restart the tomcat(in the... (1 Reply)
Discussion started by: praveen265
1 Replies

4. Shell Programming and Scripting

Two variables in output file name nested for loops

I am trying to use two nested for loops to process some files and then create a new file using both variables in the output file name. I have several files in this naming style: S1_L3_all_R1.fastq S1_L3_all_R2.fastq S1_L4_all_R1.fastq S1_L4_all_R2.fastq . . S1_L8_all_R1.fastq... (3 Replies)
Discussion started by: aminards
3 Replies

5. Shell Programming and Scripting

bash loops

hello i'm writing a script and I want to use a for loop inside a while loop as following: while read line; do echo $line for i in $vrm; do echo $i done done < './contacts' when i use just the while loop it prints the lines from file ./contacts just... (13 Replies)
Discussion started by: vlm
13 Replies

6. Homework & Coursework Questions

Bash if and loops help

Use and complete the template provided. The entire template must be completed. If you don't, your post may be deleted! 1. The problem statement, all variables and given/known data: Your shell script should continue to execute until the user selects option 4 2. Relevant commands, code,... (2 Replies)
Discussion started by: boyboy1212
2 Replies

7. Shell Programming and Scripting

For loops with multiple variables

Hi script gurus. I have need to know how to use for loop with multiple variable. Basically lets take for example /etc/passwd file has following entries The above cat command will basically first greps the real users that have email addresses then converts ':' to '+' then using cut... (4 Replies)
Discussion started by: sparcguy
4 Replies

8. Shell Programming and Scripting

arrays and while loops in bash

hi guys, i have an array called ARRAY which has elements in it... i am trying to assign elements of ARRAY to master_array.. i get a =: command not found error.. i=0 while do ${master_array}=${ARRAY} ((i++)) done is there something i am missing? (4 Replies)
Discussion started by: npatwardhan
4 Replies

9. Shell Programming and Scripting

scripting headache... loops & variables

Surely there's an easier way to do this, lets see if anyone knows! I am new to scripting so go easy on me! I have the following script and at the moment it doesn't work and I believe the problem is that I am using a while loop within a while loop. When I run the script using sh -x I can see... (6 Replies)
Discussion started by: StevePace
6 Replies

10. UNIX for Dummies Questions & Answers

Variables being worked on inside of loops

I have a while read loop that reads values inside of a file and then performs an expr operation on each. Everything works fine, the way it's supposed to but, once the loop is finished, I can not access the variable that I used inside of the loop (but that variable was created outside of the... (7 Replies)
Discussion started by: yongho
7 Replies

Featured Tech Videos