Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Array lost its values??

25 views
Skip to first unread message

hehe2046

unread,
Oct 12, 2012, 4:41:58 AM10/12/12
to
$ unzip -qq -l test.zip
0 10-12-2012 14:23 a
0 10-12-2012 14:23 aa
0 10-12-2012 14:23 aaa
0 10-12-2012 14:23 b
0 10-12-2012 14:23 bb
0 10-12-2012 14:23 bbb
0 10-12-2012 14:23 c
0 10-12-2012 14:23 cc
0 10-12-2012 14:23 ccc


My scripts:

$ cat a.sh
#! /bin/bash
zipfile=$1
pattern=$2
i=0
unzip -qq -l ${zipfile} | grep ${pattern} | while read a b c d
do
i=$((i+1))
X[$i]="${d}"
echo "$i) ${X[$i]}"
done
echo "X[*] = \"${X[*]}\""

$ a.sh test.zip a
1) a
2) aa
3) aaa
X[*] = ""

I expected it should be:
1) a
2) aa
3) aaa
X[*] = "a aa aaa"

another script b.sh:
#! /bin/bash
i=0
for k in a b c d; do
i=$((i+1))
X[$i]="${k}"
echo "$i) ${X[$k]}"
done
echo "X[*] = \"${X[*]}\""

$ ./b.sh
1) a
2) b
3) c
4) d
X[*] = "a b c d" <==== this is expected

Why array X lost its values in script a.sh?


my bash version:
GNU bash, version 4.2.37(1)-release (i686-redhat-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.


Thanks



Janis Papanagnou

unread,
Oct 12, 2012, 7:18:51 AM10/12/12
to
I see all the values. What is your problem?

You may be puzzled about the results of ${X[*]} ?
The use "${X[@]}". Try...

printf "'%s'\n" "${X[*]}"
printf "'%s'\n" "${X[@]}"


Janis

Lem Novantotto

unread,
Oct 12, 2012, 7:46:48 AM10/12/12
to
hehe2046 ha scritto:

> unzip -qq -l ${zipfile} | grep ${pattern} | while read a b c d

When you have pipes, you have subshells: each command in a pipeline is
executed as a separate process (i.e., in a subshell).

So you're setting an array in a subshell, and then you want it printed
out in a parent shell. No good. See:

$ echo readme | while read a ; do echo $a ; done ; echo $a
readme

$
--
Bye, Lem
Ceterum censeo ISLAM esse delendum
_________________________________________________________________
Non sprecare i cicli idle della tua CPU, né quelli della tua GPU.
http://www.worldcommunitygrid.org/index.jsp
http://www.rnaworld.de/rnaworld/ http://home.edges-grid.eu/home/
http://www.gpugrid.net/

Janis Papanagnou

unread,
Oct 12, 2012, 8:16:52 AM10/12/12
to
On 12.10.2012 13:46, Lem Novantotto wrote:
> hehe2046 ha scritto:
>
>> unzip -qq -l ${zipfile} | grep ${pattern} | while read a b c d
>
> When you have pipes, you have subshells: each command in a pipeline is
> executed as a separate process (i.e., in a subshell).

And one solution for that issue could be

while read a b c d
do
...
done < <( unzip -qq -l "${zipfile}" | grep "${pattern}" )

so that the while loop is not executed in a subshell.

Janis

Janis Papanagnou

unread,
Oct 12, 2012, 8:19:54 AM10/12/12
to
On 12.10.2012 13:18, Janis Papanagnou wrote:
> On 12.10.2012 10:41, hehe2046 wrote:
>> [...]
>> My scripts:
>>
>> $ cat a.sh

(I completely missed script a.sh - doh!)

>> [...]
>>
>> another script b.sh:
>> [...]
>> Why array X lost its values in script a.sh?

See Lem's explanation and my followup to his posting.

Janis

> [...]

Ben Bacarisse

unread,
Oct 12, 2012, 9:29:06 AM10/12/12
to
hehe2046 <jjerr...@gmail.com> writes:

> $ unzip -qq -l test.zip
> 0 10-12-2012 14:23 a
> 0 10-12-2012 14:23 aa
> 0 10-12-2012 14:23 aaa
> 0 10-12-2012 14:23 b
> 0 10-12-2012 14:23 bb
> 0 10-12-2012 14:23 bbb
> 0 10-12-2012 14:23 c
> 0 10-12-2012 14:23 cc
> 0 10-12-2012 14:23 ccc
>
>
> My scripts:
>
> $ cat a.sh
> #! /bin/bash
> zipfile=$1
> pattern=$2
> i=0
> unzip -qq -l ${zipfile} | grep ${pattern} | while read a b c d
> do
> i=$((i+1))
> X[$i]="${d}"
> echo "$i) ${X[$i]}"
> done
> echo "X[*] = \"${X[*]}\""

The problem's been explained, but here's another possible solution:

X=($(unzip -qq -l "$1" | awk '$4 ~ /'"$2"'/ {print $4}'))

<snip>
--
Ben.

Lem Novantotto

unread,
Oct 12, 2012, 2:18:49 PM10/12/12
to
Janis Papanagnou ha scritto:

> And one solution for that issue could be
>
> while read a b c d do
> ...
> done < <( unzip -qq -l "${zipfile}" | grep "${pattern}" )
>
> so that the while loop is not executed in a subshell.

Sure. :)

Just for the sake of curiosity, using ksh another solution could be a
coprocess ("|&").
For example:

$ print -e "a\naa\naaa" | grep -o "a*" |&
[1] 14777
$ unset X
[1] + Done print -e "a\naa\naaa" | grep -o "a*" |&
$ while read -p x; do print ${x}yes; X+=( $x ); done; echo ${X[*]}
ayes
aayes
aaayes
a aa aaa

hehe2046

unread,
Oct 17, 2012, 11:46:00 PM10/17/12
to
Lem is right on this!

If I change to KSH, my a.sh works fine.
$cat a.sh
$! /bin/ksh
zipfile=$1
pattern=$2
i=0
unzip -qq -l ${zipfile} | grep ${pattern} | while read a b c d
do
i=$((i+1))
X[$i]="${d}"
echo "$i) ${X[$i]}"
done
echo "X[*]= \"${X[*]}\""
printf "%s\n" "${X[*]}"
echo "--"
printf "%s\n" "${X[@]}"

$./a.sh test.zip a
$ ./a.sh test.zip a
1) a
2) aa
3) aaa
X[*]= "a aa aaa"
a aa aaa
--
a
aa
aaa

For the pipeline, it is difference between bash and ksh

in ksh manual:
"Each command, except possibly the last, is run as a separate process;

while in bash manual:
"Each command in a pipeline is executed as a separate process (i.e., in a subshell)." as Lem pasted.

So my a.sh works find in ksh because the while doesn't run in subshell.
Then I add ps -e f in my script to approve this:

$ cat a.sh
#! /bin/ksh
zipfile=$1
pattern=$2
i=0
unzip -qq -l ${zipfile} | grep ${pattern} | while read a b c d
do
ps -e f
sleep 3
i=$((i+1))
X[$i]="${d}"
echo "$i) ${X[$i]}"
done
echo "X[*]= \"${X[*]}\""
printf "%s\n" "${X[*]}"
echo "--"
printf "%s\n" "${X[@]}"

$ ./a.sh test.zip a

4308 pts/2 Ss 0:00 \_ bash
7230 pts/2 S+ 0:00 | \_ /bin/ksh ./a.sh test.zip a
7235 pts/2 R+ 0:00 | \_ ps -e f

If I changed ksh to bash, I got:

4308 pts/2 Ss 0:00 \_ bash
7261 pts/2 S+ 0:00 | \_ /bin/bash ./a.sh test.zip a
7264 pts/2 S+ 0:00 | \_ /bin/bash ./a.sh test.zip a
7265 pts/2 R+ 0:00 | \_ ps -e f


Thanks everyone for the reply.
hehe2046

--http://compgroups.net/comp.unix.shell/array-lost-its-values/1949314


0 new messages