Help on bash script?

dpk dpk at dpk.net
Fri Aug 12 02:02:06 GMT 2005


On Fri, 12 Aug 2005, Xu Qiang wrote:

> Hi, all:
>
> I don't know if this is the right list to ask this question. But since I
> didn't find a bash script mail list and you guys are always so helpful,
> then...
>
> Here are an excerpt of a bash script:
>
> -------------------------------------------------------
>
> #!/bin/bash
> # saveLogs.sh - Bourne Again Shell script
> ...
> 		find / -type f -name core -print | while read COREFILE ; do
> 			NCOREFILES=$[ $NCOREFILES + 1 ] # a bit strange - xq
> 			echo $NCOREFILES # xq
> ...
> -------------------------------------------------------
> ...
> 1. The way of incrementing the variable NCOREFILES. Why does it use the
> formula of "NCOREFILES=$[ $NCOREFILES + 1 ]", and not the direct way of
> "NCOREFILES=$NCOREFILES+1"?

If that was done, NCOREFILES would end up looking like:

+1+1+1+1+1+1+1

as bash does not automatically differentiate between numeric and string
variables. What the funky looking construct does is convince bash to treat
it as a numeric/arithmetic expression.

> 2. What confused me most is the value of the variable NCOREFILES
> ($NCOREFILES). Say there is just 1 core file, then because the initial
> value of NCOREFILES is 0, it will be incremented to 1. Yes, this is the
> value in the do-while loop. But outside the loop and if-block, the value
> of NCOREFILES is reverted back to 0 - its initial value.
>
> It is a local variable, so any modification to it should be valid as
> long as we are still in the scope of the function, right? I am really
> lossed at this phenomenon.

As soon as you used the pipe, to the while, you entered a sub-shell.
There's no way (that I'm aware of anyways) to get the sub-shell's
variables sent back up to the parent.

You could do something along the lines of:

for cf in `find -X -type f -name core -print`
do
	# do stuff with "$cf"
	NCOREFILES=$[ $NCOREFILES + 1 ]
done

(the -X helps prevent problems when faced with spaces embedded in the
path)

By the way, on FreeBSD systems, the default core filename format is
"%N.core" (see "man core") where %N is the name of the program that
dumped. You'd need to expand your find with -name \*.core . If you wanted
to get really fancy, you could parse "sysctl kern.corefile" to find out
the current filename format and use that in your find, but most people
leave that sysctl at its default, so it probably wouldn't be necessary.


More information about the freebsd-questions mailing list