On Wednesday 13 February 2008 20:41, David C. Rankin wrote:
Listmates,
I have run into a bash problem with a simple for loop I don't understand and would like input from the gurus to determine if the tldp documentation is in error or if it is me. Safe money says it's me, but here is the situation.
I am using example 9.1.2.2. from the following link to construct a simple for loop to extract a directory full of zip files:
http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_09_01.html
It sounds like someone needs to submit some feedback to the author or maintainer of that document.
The example give is:
...
So I created the following:
#!/bin/bash LIST="$(ls *.zip)" for i in "$LIST"; do unzip $i -d /mnt/nemesis-cfg/home/samba/computer/software/fonts/extract echo "Unzipped: $i to ../extract" done exit 0
It didn't work?? The echo statement showed that $i was receiving the entire $LIST and the loop was only executing once instead of once for each entry in $LIST. Fiddling with it, I got it to work by removing the quotes "" from $LIST in the loop definition like this:
#!/bin/bash LIST="$(ls *.zip)" for i in $LIST; do unzip $i -d /mnt/nemesis-cfg/home/samba/computer/software/fonts/extract echo "Unzipped: $i to ../extract" done exit 0
I understand enough to realize the quotes affect bash expansion, but I am curious as to whether the tldp example is in error. What says the brain trust?
That's what quotes do. They create a single string. The ones where LIST is defined are required because a shell variable (that is not an array) can have only a single value and ordinary parsing would break the output of ls at each occurrence of a (run of) whitespace characters. The one in the "for" loop, where any number of words is allowed, causes there to be only one, holding the entire output from the "ls" invocation. I personally like to use array variables in BASH scripting. They're very hand because they can be spread across multiple lines _without_ using backslashes and by putting a single value on each line, you can easily comment out certain values by commenting the line that contains them within the array initialization. Also, you can get item-by-item quoting when expanding an array. Consider this array: numbers=( 0 I two 3 ) for number in "${numbers[@]}"; do echo $number done Echo will be invoked four times in this loop. This variant get all the array elements expanded in single quoted string: for number in "${numbers[*]}"; do echo $number done In this case, echo will be invoked only once. When you combine arrays with command substitution (the $( command ) notation) and pipes, you can get pretty fancy about generating value lists to operate on.
-- David C. Rankin, J.D., P.E.
Randall Schulz -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org