Re: sourcing script file from inside a function doesn't work anymore

2014-05-12 Thread thioroup8

Hi all,

Chet, I compiled a 4.3.11 from scratch.
Then I applied your fix and compiled again.
I executed my test program I attached in my bug report and it works like 
a charm and like bash 4.2.


Now I'm going to try with several scripts I wrote which were affected by 
this bug...


Thank you all for your time

Best regards
Jean-Philippe


Le 12/05/2014 17:31, Chet Ramey a écrit :

On 5/12/14, 9:33 AM, Geir Hauge wrote:

2014-05-12 14:11 GMT+02:00 Greg Wooledge :


On Sat, May 10, 2014 at 12:22:40PM +0200, thioroup8 wrote:

Now, I source it from inside a function: I obtain following error

message:

bash: declare: tmp: not found
I think this problem raises in the particular case of involving array
variables definitions inside sourced bash script file...
   cat << "EOF" > "${file_to_be_sourced}"
declare -a tmp='([0]="1" [1]="2")'
EOF

The problem is that you are using "declare" within the file-to-be-sourced.
When you source the file inside a function, Bash runs the declare command
within the context of the function, where declare has the same meaning as
"local".  Thus, it makes the variable local to the function.


There really is a bug here, a weird one. Using a simplified script, we
see that this works as expected:

Yep. Thanks for the report.  The issue is that the `placeholder' attribute
doesn't get unset when the argument is quoted -- it takes a different code
path than when it's unquoted.  I've attached a patch for people to
experiment with.

Chet






Re: sourcing script file from inside a function doesn't work anymore

2014-05-12 Thread Chet Ramey
On 5/12/14, 9:33 AM, Geir Hauge wrote:
> 2014-05-12 14:11 GMT+02:00 Greg Wooledge :
> 
>> On Sat, May 10, 2014 at 12:22:40PM +0200, thioroup8 wrote:
>>> Now, I source it from inside a function: I obtain following error
>> message:
>>> bash: declare: tmp: not found
>>> I think this problem raises in the particular case of involving array
>>> variables definitions inside sourced bash script file...
>>
>>>   cat << "EOF" > "${file_to_be_sourced}"
>>> declare -a tmp='([0]="1" [1]="2")'
>>> EOF
>>
>> The problem is that you are using "declare" within the file-to-be-sourced.
>> When you source the file inside a function, Bash runs the declare command
>> within the context of the function, where declare has the same meaning as
>> "local".  Thus, it makes the variable local to the function.
> 
> 
> There really is a bug here, a weird one. Using a simplified script, we
> see that this works as expected:

Yep. Thanks for the report.  The issue is that the `placeholder' attribute
doesn't get unset when the argument is quoted -- it takes a different code
path than when it's unquoted.  I've attached a patch for people to
experiment with.

Chet

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/
*** ../bash-4.3-patched/arrayfunc.c	2014-03-28 10:54:21.0 -0400
--- arrayfunc.c	2014-05-12 11:19:00.0 -0400
***
*** 180,183 
--- 180,184 
FREE (newval);
  
+   VUNSETATTR (entry, att_invisible);	/* no longer invisible */
return (entry);
  }


Re: sourcing script file from inside a function doesn't work anymore

2014-05-12 Thread Greg Wooledge
On Mon, May 12, 2014 at 03:33:34PM +0200, Geir Hauge wrote:
> Oddly, the quotes seem to matter; changing array='(x)' to array=(x)
> makes it work...
> 
> $ f() { source <(printf "declare -a array=(x); declare -p array\n"); }; f
> declare -a array='([0]="x")'

OK, this also happens on my system.  In fact this is the first time I've
ever seen array='(...)' instead of array=(...) and I had no idea the
quoted version works outside of a function.  It seems like an incredibly
strange syntax; without the explicit "declare -a" it would be initializing
a string variable.

But this doesn't change the fact that the original poster is making a
local variable inside the function, which won't be visible outside it.



Re: sourcing script file from inside a function doesn't work anymore

2014-05-12 Thread Geir Hauge
2014-05-12 14:11 GMT+02:00 Greg Wooledge :

> On Sat, May 10, 2014 at 12:22:40PM +0200, thioroup8 wrote:
> > Now, I source it from inside a function: I obtain following error
> message:
> > bash: declare: tmp: not found
> > I think this problem raises in the particular case of involving array
> > variables definitions inside sourced bash script file...
>
> >   cat << "EOF" > "${file_to_be_sourced}"
> > declare -a tmp='([0]="1" [1]="2")'
> > EOF
>
> The problem is that you are using "declare" within the file-to-be-sourced.
> When you source the file inside a function, Bash runs the declare command
> within the context of the function, where declare has the same meaning as
> "local".  Thus, it makes the variable local to the function.


There really is a bug here, a weird one. Using a simplified script, we
see that this works as expected:

$ source <(printf "declare -a array='(x)'; declare -p array\n")
declare -a array='([0]="x")'


Wrapping it in a function should yield the same output, but doesn't:

$ f() { source <(printf "declare -a array='(x)'; declare -p array\n"); }; f
bash: declare: array: not found


And while declare -p array fails to "find" the array, declare -p
(without a name) does list it:

$ f() { source <(printf "declare -a array='(x)'; declare -p array; declare
-p | grep array= \n"); }; f
bash: declare: array: not found
declare -a array='([0]="x")'


Oddly, the quotes seem to matter; changing array='(x)' to array=(x)
makes it work...

$ f() { source <(printf "declare -a array=(x); declare -p array\n"); }; f
declare -a array='([0]="x")'

-- 
Geir Hauge


Re: sourcing script file from inside a function doesn't work anymore

2014-05-12 Thread Greg Wooledge
On Sat, May 10, 2014 at 12:22:40PM +0200, thioroup8 wrote:
> Now, I source it from inside a function: I obtain following error message:
> bash: declare: tmp: not found
> I think this problem raises in the particular case of involving array 
> variables definitions inside sourced bash script file...

>   cat << "EOF" > "${file_to_be_sourced}"
> declare -a tmp='([0]="1" [1]="2")'
> EOF

The problem is that you are using "declare" within the file-to-be-sourced.
When you source the file inside a function, Bash runs the declare command
within the context of the function, where declare has the same meaning as
"local".  Thus, it makes the variable local to the function.

If you only put tmp=(...) in the file, it works as you expect.  Which
is fine as long as you're only using normal arrays, and not associative
arrays.

If you want to declare associative arrays in this way, you'll need to
add the -g option to declare, which is available in bash 4.2 and later.
This makes the variable global instead of local.

There is unfortunately no middle ground between local and variable if
you must use "declare" (i.e. there is no way to mimic tmp=(foo bar)
to use default scoping with an associative array because you can't skip
the declare -A step on those), nor is there a way to mimic declare -g -A
in bash 4.0 or 4.1.

The only other option is to issue the declare -A outside of the function
(either in global scope, or in the outermost function where the variable
needs to be available), and then use tmp=(...) (without a declare) in
the file-to-be-sourced.



sourcing script file from inside a function doesn't work anymore

2014-05-10 Thread thioroup8

Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' 
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-pc-linux-gnu' 
-DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' 
-DSHELL -DHAVE_CONFIG_H   -I.  -I../. -I.././include -I.././lib 
-D_FORTIFY_SOURCE=2 -g -O2 -fstack-protector --param=ssp-buffer-size=4 
-Wformat -Werror=format-security -Wall
uname output: Linux thioroup8-laptop 3.13.0-26-generic #48-Ubuntu SMP 
Wed May 7 23:31:02 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

Machine Type: x86_64-pc-linux-gnu

Bash Version: 4.3
Patch Level: 11
Release Status: release

Description:
I write a bash script file containing variables definitions.
From another bash script file, I source it from outside any function: 
in this case all is working fine as expected.

Now, I source it from inside a function: I obtain following error message:
bash: declare: tmp: not found
I think this problem raises in the particular case of involving array 
variables definitions inside sourced bash script file...


Repeat-By:
You can execute the script below:
#!/bin/bash

generate_file_to_be_sourced()
{
  local file_to_be_sourced
  file_to_be_sourced="$(mktemp)"
  cat << "EOF" > "${file_to_be_sourced}"
declare -a tmp='([0]="1" [1]="2")'
EOF
  echo "${file_to_be_sourced}"
}

foo()
{
  source "${g_file_to_be_sourced}"

  if declare -p tmp &> /dev/null && [ "${#tmp[@]}" = "2" ]
  then
echo "test #2: OK"
  else
echo "test #2: NOK"
  fi
  unset tmp
}

echo "bash version: ${BASH_VERSION}"
echo

declare -r g_file_to_be_sourced="$(generate_file_to_be_sourced)"
echo "content of file to be sourced:"
cat "${g_file_to_be_sourced}"
echo

source "${g_file_to_be_sourced}"

if declare -p tmp &> /dev/null && [ "${#tmp[@]}" = "2" ]
then
  echo "test #1: OK"
else
  echo "test #1: NOK"
fi
unset tmp

foo

rm "${g_file_to_be_sourced}"

If you need further informations, don't hesitate to ask me...

Best regards
Jean-Philippe