Re: ${!variable@operator} does not work for variables without values; inconsistencies between present and absent [@] for @A and @a

2020-02-20 Thread Arfrever Frehtes Taifersar Arahesis
2020-02-20 21:36 GMT+01:00, Chet Ramey :
> On 2/19/20 4:03 PM, Arfrever Frehtes Taifersar Arahesis wrote:
>> ${!variable@operator} does not work for variables without values.
>> See empty values for all occurrences of ${!var@...} below.
>>
>> ${variable@A} does not work for scalar variables without values, but
>> interestingly ${variable[@]@A} works for them.
>> See difference between ${VAR1@A} and ${VAR1[@]@A} below.
>> However neither ${variable@A} nor ${variable[@]@A} works for arrays
>> without values.
>>
>> Both ${variable@a} and ${variable[@]@a} work for scalar variables
>> without values.
>> However ${variable[@]@a} does not work for arrays without values.
>
> Same answer as previously: maybe it should display the attributes
> even thought the variable is unset.

Yes, I think that @A, [@]@A, @a and [@]@a should work for unset variables.

As mentioned previously, @a and [@]@a already works for unset scalar variables,
and @a works for unset arrays, but [@]@a does not work for unset
arrays (while it works for set arrays).

Examples for @a and [@]@a:

$ declare -lr VAR1
$ declare -lr VAR2=zzz
$ declare -alr VAR3
$ declare -alr VAR4=(zzz zzz)
$ declare -Alr VAR5
$ declare -Alr VAR6=([0]=zzz [1]=zzz)
$ declare -p VAR{1,2,3,4,5,6}
declare -rl VAR1
declare -rl VAR2="zzz"
declare -arl VAR3
declare -arl VAR4=([0]="zzz" [1]="zzz")
declare -Arl VAR5
declare -Arl VAR6=([1]="zzz" [0]="zzz" )
$ echo "${VAR1@a}"
rl
$ echo "${VAR1[@]@a}"
rl
$ echo "${VAR2@a}"
rl
$ echo "${VAR2[@]@a}"
rl
$ echo "${VAR3@a}"
arl
$ echo "${VAR3[@]@a}"

$ echo "${VAR4@a}"
arl
$ echo "${VAR4[@]@a}"
arl arl
$ echo "${VAR5@a}"
Arl
$ echo "${VAR5[@]@a}"

$ echo "${VAR6@a}"
Arl
$ echo "${VAR6[@]@a}"
Arl Arl
$

--
Arfrever Frehtes Taifersar Arahesis



Re: ${!variable@operator} does not work for variables without values; inconsistencies between present and absent [@] for @A and @a

2020-02-20 Thread Arfrever Frehtes Taifersar Arahesis
Chet Ramey  2020-02-20 21:22 UTC:
> On 2/19/20 7:46 PM, Arfrever Frehtes Taifersar Arahesis wrote:
>> But I am not interested in any ${!varname[@]}, but instead in applying
>> @operator transformations.
>
> OK, let's see how these work.
>
> Given the following
>
> VAR2=(aaa bbb)
> varname=VAR2
>
> What does
>
> echo ${!varname[@]@Q}
>
> output?
>
> You first have to expand `varname[@]' as an indirect reference. Since
> varname is a scalar variable, varname[@] expands to the same thing as
> varname, which is VAR2. Now you expand VAR2, which, since VAR2 is an
> array variable, is the same as VAR2[0]. That gives you "aaa", so the
> output is 'aaa'.

Your explanation is convincing for varname=VAR2 but now I would expect
different results for varname=VAR2[@].

Current actual results:
$ VAR2=(aaa bbb)
$ varname="VAR2[@]"
$ echo "${VAR2@Q}"
'aaa'
$ echo "${VAR2[@]@Q}"
'aaa' 'bbb'
$ echo "${!varname@Q}"

$ echo "${!varname[@]@Q}"

$

Expected results for last 2 commands:

$ echo "${!varname@Q}"
'aaa' 'bbb'
$ echo "${!varname[@]@Q}"
bash: ${VAR2[@][@]@Q}: bad substitution# This is example from
direct usage of [@][@]
$

--
Arfrever Frehtes Taifersar Arahesis



Re: ${!variable@operator} does not work for variables without values; inconsistencies between present and absent [@] for @A and @a

2020-02-20 Thread Arfrever Frehtes Taifersar Arahesis
Chet Ramey  2020-02-20 20:41 UTC:
> On 2/19/20 5:22 PM, Arfrever Frehtes Taifersar Arahesis wrote:
>>> ${variable@A} does not work for scalar variables without values, but
>>> interestingly ${variable[@]@A} works for them.
>>
>> More precisely, ${variable[@]@A} is non-empty, but not exactly correct.
>>
>>> See difference between ${VAR1@A} and ${VAR1[@]@A} below.
>>
>> ${VAR1[@]@A} is:
>> declare -rl VAR1=''"
>> But should be:
>> declare -rl VAR1
>> As in output of 'declare -p VAR1'.
>
> The output is two blank lines:
>
> $ cat x6b
> declare -lr VAR1
>
> echo ${VAR1@A}
> echo ${VAR1[@]@A}
> $ ../bash-5.0-patched/bash ./x6b
>
>

Even more strangely, quoting apparently matters...

$ declare -lr VAR1
$ echo ${VAR1@A}

$ echo ${VAR1[@]@A}

$ echo "${VAR1@A}"

$ echo "${VAR1[@]@A}"
declare -rl VAR1=''
$ declare -p VAR1
declare -rl VAR1
$

> The question is whether the unset variables should display commands to
> set the attributes (@A) or display any attributes (@a).

I think that it would be expected that @A prints the same as 'declare
-p' for given variable.

--
Arfrever Frehtes Taifersar Arahesis



Re: ${!variable@operator} does not work for variables without values; inconsistencies between present and absent [@] for @A and @a

2020-02-19 Thread Arfrever Frehtes Taifersar Arahesis
Eli Schwartz  2020-02-20 23:49 UTC:
> Your examples are all (still) broken.

This would affect only 10 examples from 120, so only 8.33 % of
examples, far from all examples.

> You cannot use ${!ref[@]}, you need the array subscript as part of the
> set value of "ref" and then indirectly refer to ref.
>
> $ declare -A VAR2=([foo]=bar [baz]="how interesting")
> $ args "${!VAR2[@]}"
>  
> ...
> And, as predicted, if instead of using ${!ref[@]} you use
> ${!varname[@]}, you get meaningful information.

But I am not interested in any ${!varname[@]}, but instead in applying
@operator transformations.

>From `man bash`:
```
   ${parameter@operator}
  Parameter  transformation.   The  expansion is either a
transformation of the value of parameter or information about
parameter itself, de‐
  pending on the value of operator.  Each operator is a
single letter:

  Q  The expansion is a string that is the value of
parameter quoted in a format that can be reused as input.
  E  The expansion is a string that is the value of
parameter with backslash escape sequences expanded as with the $'...'
quoting  mecha‐
 nism.
  P  The  expansion  is  a string that is the result
of expanding the value of parameter as if it were a prompt string (see
PROMPTING be‐
 low).
  A  The expansion is a string in the form of an
assignment statement or declare command that, if evaluated, will
recreate parameter with
 its attributes and value.
  a  The expansion is a string consisting of flag
values representing parameter's attributes.

  If parameter is @ or *, the operation is applied to each
positional parameter in turn, and the expansion is the resultant list.
If parame‐
  ter is an array variable subscripted with @ or *, the
operation is applied to each member of the array in turn, and the
expansion  is  the
  resultant list.
```

Is there any way for using ${!variable} combined with
${variable@operator} to get useful results for multi-elemental arrays?
If not, then I can still use `eval` :) .

$ ARRAY=(あ い う え お)
$ REF=ARRAY
$ eval "echo \"\${${REF}[@]@A}\""
declare -a ARRAY=([0]="あ" [1]="い" [2]="う" [3]="え" [4]="お")
$ eval "echo \"\${${REF}[@]@a}\""
a a a a a
$ echo "${ARRAY[@]@A}"
declare -a ARRAY=([0]="あ" [1]="い" [2]="う" [3]="え" [4]="お")
$ echo "${ARRAY[@]@a}"
a a a a a
$

Majority (3 of 4) of bugs reported by me in this thread are unaffected
by above discussion about ${!...} and are certainly still valid.

--
Arfrever Frehtes Taifersar Arahesis



Re: ${!variable@operator} does not work for variables without values; inconsistencies between present and absent [@] for @A and @a

2020-02-19 Thread Arfrever Frehtes Taifersar Arahesis
While described problems exist, there were typos in original reproduction steps.

Corrected output also reveals another bug:
${!variable[@]@A} for (indexed or associative) arrays does not include indexes.
Example part of output:
var=VAR4
${!var@A}:'declare -arl VAR4='zzz''
${!var[@]@A}: 'declare -arl VAR4='zzz''
${VAR4@A}:'declare -arl VAR4='zzz''
${VAR4[@]@A}: 'declare -arl VAR4=([0]="zzz")'

${!var[@]@A} would be expected to be the same as ${VAR4[@]@A}.


Corrected full reproduction steps with better formatting of 'for' loops:

$ declare -lr VAR1
$ declare -lr VAR2=zzz
$ declare -alr VAR3
$ declare -alr VAR4=(zzz)
$ declare -Alr VAR5
$ declare -Alr VAR6=([0]=zzz)
$ declare -p VAR{1,2,3,4,5,6}
declare -rl VAR1
declare -rl VAR2="zzz"
declare -arl VAR3
declare -arl VAR4=([0]="zzz")
declare -Arl VAR5
declare -Arl VAR6=([0]="zzz" )
$ for operator in Q E P A a ; do
>   for var in VAR{1,2,3,4,5,6} ; do
> echo "var=${var}"
> eval "echo \"\\\${!var@${operator}}:'\${!var@${operator}}'\""
> eval "echo \"\\\${!var[@]@${operator}}: '\${!var[@]@${operator}}'\""
> eval "echo \"\\\${${var}@${operator}}:'\${${var}@${operator}}'\""
> eval "echo \"\\\${${var}[@]@${operator}}: '\${${var}[@]@${operator}}'\""
> echo
>   done
> done
var=VAR1
${!var@Q}:''
${!var[@]@Q}: ''
${VAR1@Q}:''
${VAR1[@]@Q}: ''

var=VAR2
${!var@Q}:''zzz''
${!var[@]@Q}: ''zzz''
${VAR2@Q}:''zzz''
${VAR2[@]@Q}: ''zzz''

var=VAR3
${!var@Q}:''
${!var[@]@Q}: ''
${VAR3@Q}:''
${VAR3[@]@Q}: ''

var=VAR4
${!var@Q}:''zzz''
${!var[@]@Q}: ''zzz''
${VAR4@Q}:''zzz''
${VAR4[@]@Q}: ''zzz''

var=VAR5
${!var@Q}:''
${!var[@]@Q}: ''
${VAR5@Q}:''
${VAR5[@]@Q}: ''

var=VAR6
${!var@Q}:''zzz''
${!var[@]@Q}: ''zzz''
${VAR6@Q}:''zzz''
${VAR6[@]@Q}: ''zzz''

var=VAR1
${!var@E}:''
${!var[@]@E}: ''
${VAR1@E}:''
${VAR1[@]@E}: ''

var=VAR2
${!var@E}:'zzz'
${!var[@]@E}: 'zzz'
${VAR2@E}:'zzz'
${VAR2[@]@E}: 'zzz'

var=VAR3
${!var@E}:''
${!var[@]@E}: ''
${VAR3@E}:''
${VAR3[@]@E}: ''

var=VAR4
${!var@E}:'zzz'
${!var[@]@E}: 'zzz'
${VAR4@E}:'zzz'
${VAR4[@]@E}: 'zzz'

var=VAR5
${!var@E}:''
${!var[@]@E}: ''
${VAR5@E}:''
${VAR5[@]@E}: ''

var=VAR6
${!var@E}:'zzz'
${!var[@]@E}: 'zzz'
${VAR6@E}:'zzz'
${VAR6[@]@E}: 'zzz'

var=VAR1
${!var@P}:''
${!var[@]@P}: ''
${VAR1@P}:''
${VAR1[@]@P}: ''

var=VAR2
${!var@P}:'zzz'
${!var[@]@P}: 'zzz'
${VAR2@P}:'zzz'
${VAR2[@]@P}: 'zzz'

var=VAR3
${!var@P}:''
${!var[@]@P}: ''
${VAR3@P}:''
${VAR3[@]@P}: ''

var=VAR4
${!var@P}:'zzz'
${!var[@]@P}: 'zzz'
${VAR4@P}:'zzz'
${VAR4[@]@P}: 'zzz'

var=VAR5
${!var@P}:''
${!var[@]@P}: ''
${VAR5@P}:''
${VAR5[@]@P}: ''

var=VAR6
${!var@P}:'zzz'
${!var[@]@P}: 'zzz'
${VAR6@P}:'zzz'
${VAR6[@]@P}: 'zzz'

var=VAR1
${!var@A}:''
${!var[@]@A}: ''
${VAR1@A}:''
${VAR1[@]@A}: 'declare -rl VAR1='''

var=VAR2
${!var@A}:'declare -rl VAR2='zzz''
${!var[@]@A}: 'declare -rl VAR2='zzz''
${VAR2@A}:'declare -rl VAR2='zzz''
${VAR2[@]@A}: 'declare -rl VAR2='zzz''

var=VAR3
${!var@A}:''
${!var[@]@A}: ''
${VAR3@A}:''
${VAR3[@]@A}: ''

var=VAR4
${!var@A}:'declare -arl VAR4='zzz''
${!var[@]@A}: 'declare -arl VAR4='zzz''
${VAR4@A}:'declare -arl VAR4='zzz''
${VAR4[@]@A}: 'declare -arl VAR4=([0]="zzz")'

var=VAR5
${!var@A}:''
${!var[@]@A}: ''
${VAR5@A}:''
${VAR5[@]@A}: ''

var=VAR6
${!var@A}:'declare -Arl VAR6='zzz''
${!var[@]@A}: 'declare -Arl VAR6='zzz''
${VAR6@A}:'declare -Arl VAR6='zzz''
${VAR6[@]@A}: 'declare -Arl VAR6=([0]="zzz" )'

var=VAR1
${!var@a}:''
${!var[@]@a}: ''
${VAR1@a}:'rl'
${VAR1[@]@a}: 'rl'

var=VAR2
${!var@a}:'rl'
${!var[@]@a}: 'rl'
${VAR2@a}:'rl'
${VAR2[@]@a}: 'rl'

var=VAR3
${!var@a}:''
${!var[@]@a}: ''
${VAR3@a}:'arl'
${VAR3[@]@a}: ''

var=VAR4
${!var@a}:'arl'
${!var[@]@a}: 'arl'
${VAR4@a}:'arl'
${VAR4[@]@a}: 'arl'

var=VAR5
${!var@a}:''
${!var[@]@a}: ''
${VAR5@a}:'Arl'
${VAR5[@]@a}: ''

var=VAR6
${!var@a}:'Arl'
${!var[@]@a}: 'Arl'
${VAR6@a}:'Arl'
${VAR6[@]@a}: 'Arl'

$

--
Arfrever Frehtes Taifersar Arahesis



Re: ${!variable@operator} does not work for variables without values; inconsistencies between present and absent [@] for @A and @a

2020-02-19 Thread Arfrever Frehtes Taifersar Arahesis
> ${variable@A} does not work for scalar variables without values, but
> interestingly ${variable[@]@A} works for them.

More precisely, ${variable[@]@A} is non-empty, but not exactly correct.

> See difference between ${VAR1@A} and ${VAR1[@]@A} below.

${VAR1[@]@A} is:
declare -rl VAR1=''"
But should be:
declare -rl VAR1
As in output of 'declare -p VAR1'.

--
Arfrever Frehtes Taifersar Arahesis



Unnecessary space in 'declare -p' and [@]@A for non-empty associative arrays

2020-02-19 Thread Arfrever Frehtes Taifersar Arahesis
Notice unnecessary space before closing parenthesis for non-empty
associative arrays (VAR5, VAR6) below:

$ declare -a VAR1=() VAR2=(a) VAR3=(a b)
$ declare -A VAR4=() VAR5=([0]=a) VAR6=([0]=a [1]=b)
$ declare -p VAR{1,2,3,4,5,6}
declare -a VAR1=()
declare -a VAR2=([0]="a")
declare -a VAR3=([0]="a" [1]="b")
declare -A VAR4=()
declare -A VAR5=([0]="a" )
declare -A VAR6=([1]="b" [0]="a" )
$ echo "${VAR1[@]@A}"
declare -a VAR1=()
$ echo "${VAR2[@]@A}"
declare -a VAR2=([0]="a")
$ echo "${VAR3[@]@A}"
declare -a VAR3=([0]="a" [1]="b")
$ echo "${VAR4[@]@A}"
declare -A VAR4=()
$ echo "${VAR5[@]@A}"
declare -A VAR5=([0]="a" )
$ echo "${VAR6[@]@A}"
declare -A VAR6=([1]="b" [0]="a" )
$

(BASH 5.0.16)

--
Arfrever Frehtes Taifersar Arahesis



${!variable@operator} does not work for variables without values; inconsistencies between present and absent [@] for @A and @a

2020-02-19 Thread Arfrever Frehtes Taifersar Arahesis
${!variable@operator} does not work for variables without values.
See empty values for all occurrences of ${!var@...} below.

${variable@A} does not work for scalar variables without values, but
interestingly ${variable[@]@A} works for them.
See difference between ${VAR1@A} and ${VAR1[@]@A} below.
However neither ${variable@A} nor ${variable[@]@A} works for arrays
without values.

Both ${variable@a} and ${variable[@]@a} work for scalar variables
without values.
However ${variable[@]@a} does not work for arrays without values.
See difference between ${VAR3@a} and ${VAR3[@]@a}, and between
${VAR5@a} and ${VAR5[@]@a} below.

(BASH 5.0.16.)

$ declare -lr VAR1
$ declare -lr VAR2=zzz
$ declare -alr VAR3
$ declare -alr VAR4=(zzz)
$ declare -Alr VAR5
$ declare -Alr VAR6=([0]=zzz)
$ declare -p VAR{1,2,3,4,5,6}
declare -rl VAR1
declare -rl VAR2="zzz"
declare -arl VAR3
declare -arl VAR4=([0]="zzz")
declare -Arl VAR5
declare -Arl VAR6=([0]="zzz" )
$ for operator in Q E P A a ; do for var in VAR{1,2,3,4,5,6} ; do echo
"var=${var}" ; eval "echo \"\\\${!var@${operator}}:
'\${!${var}@${operator}}'\"" ; eval "echo \"\\\${!var[@]@${operator}}:
'\${!${var}[@]@${operator}}'\"" ; eval "echo
\"\\\${${var}@${operator}}:'\${${var}@${operator}}'\""  ; eval
"echo \"\\\${${var}[@]@${operator}}: '\${${var}[@]@${operator}}'\"" ;
echo ; done ; done
var=VAR1
${!var@Q}:''
${!var[@]@Q}: ''
${VAR1@Q}:''
${VAR1[@]@Q}: ''

var=VAR2
${!var@Q}:''
${!var[@]@Q}: ''
${VAR2@Q}:''zzz''
${VAR2[@]@Q}: ''zzz''

var=VAR3
${!var@Q}:''
${!var[@]@Q}: ''
${VAR3@Q}:''
${VAR3[@]@Q}: ''

var=VAR4
${!var@Q}:''
${!var[@]@Q}: ''
${VAR4@Q}:''zzz''
${VAR4[@]@Q}: ''zzz''

var=VAR5
${!var@Q}:''
${!var[@]@Q}: ''
${VAR5@Q}:''
${VAR5[@]@Q}: ''

var=VAR6
${!var@Q}:''
${!var[@]@Q}: ''
${VAR6@Q}:''zzz''
${VAR6[@]@Q}: ''zzz''

var=VAR1
${!var@E}:''
${!var[@]@E}: ''
${VAR1@E}:''
${VAR1[@]@E}: ''

var=VAR2
${!var@E}:''
${!var[@]@E}: ''
${VAR2@E}:'zzz'
${VAR2[@]@E}: 'zzz'

var=VAR3
${!var@E}:''
${!var[@]@E}: ''
${VAR3@E}:''
${VAR3[@]@E}: ''

var=VAR4
${!var@E}:''
${!var[@]@E}: ''
${VAR4@E}:'zzz'
${VAR4[@]@E}: 'zzz'

var=VAR5
${!var@E}:''
${!var[@]@E}: ''
${VAR5@E}:''
${VAR5[@]@E}: ''

var=VAR6
${!var@E}:''
${!var[@]@E}: ''
${VAR6@E}:'zzz'
${VAR6[@]@E}: 'zzz'

var=VAR1
${!var@P}:''
${!var[@]@P}: ''
${VAR1@P}:''
${VAR1[@]@P}: ''

var=VAR2
${!var@P}:''
${!var[@]@P}: ''
${VAR2@P}:'zzz'
${VAR2[@]@P}: 'zzz'

var=VAR3
${!var@P}:''
${!var[@]@P}: ''
${VAR3@P}:''
${VAR3[@]@P}: ''

var=VAR4
${!var@P}:''
${!var[@]@P}: ''
${VAR4@P}:'zzz'
${VAR4[@]@P}: 'zzz'

var=VAR5
${!var@P}:''
${!var[@]@P}: ''
${VAR5@P}:''
${VAR5[@]@P}: ''

var=VAR6
${!var@P}:''
${!var[@]@P}: ''
${VAR6@P}:'zzz'
${VAR6[@]@P}: 'zzz'

var=VAR1
${!var@A}:''
${!var[@]@A}: ''
${VAR1@A}:''
${VAR1[@]@A}: 'declare -rl VAR1='''

var=VAR2
${!var@A}:''
${!var[@]@A}: ''
${VAR2@A}:'declare -rl VAR2='zzz''
${VAR2[@]@A}: 'declare -rl VAR2='zzz''

var=VAR3
${!var@A}:''
${!var[@]@A}: ''
${VAR3@A}:''
${VAR3[@]@A}: ''

var=VAR4
${!var@A}:''
${!var[@]@A}: ''
${VAR4@A}:'declare -arl VAR4='zzz''
${VAR4[@]@A}: 'declare -arl VAR4=([0]="zzz")'

var=VAR5
${!var@A}:''
${!var[@]@A}: ''
${VAR5@A}:''
${VAR5[@]@A}: ''

var=VAR6
${!var@A}:''
${!var[@]@A}: ''
${VAR6@A}:'declare -Arl VAR6='zzz''
${VAR6[@]@A}: 'declare -Arl VAR6=([0]="zzz" )'

var=VAR1
${!var@a}:''
${!var[@]@a}: ''
${VAR1@a}:'rl'
${VAR1[@]@a}: 'rl'

var=VAR2
${!var@a}:''
${!var[@]@a}: ''
${VAR2@a}:'rl'
${VAR2[@]@a}: 'rl'

var=VAR3
${!var@a}:''
${!var[@]@a}: ''
${VAR3@a}:'arl'
${VAR3[@]@a}: ''

var=VAR4
${!var@a}:''
${!var[@]@a}: ''
${VAR4@a}:'arl'
${VAR4[@]@a}: 'arl'

var=VAR5
${!var@a}:''
${!var[@]@a}: ''
${VAR5@a}:'Arl'
${VAR5[@]@a}: ''

var=VAR6
${!var@a}:''
${!var[@]@a}: ''
${VAR6@a}:'Arl'
${VAR6[@]@a}: 'Arl'

$

--
Arfrever Frehtes Taifersar Arahesis



Inconsistent termination of function when 'local' tries to override read-only variable

2020-02-19 Thread Arfrever Frehtes Taifersar Arahesis
When scalar variable is read-only, then calling 'local' for this
variable (regardless of presence of value in assignment) is non-fatal
and subsequent commands in function are executed.

When (indexed or associative) array is read-only, then calling 'local
-a' or 'local -A' (without value) for this variable is non-fatal and
subsequent commands in function are executed.

Trying to set global variable without using 'local' is fatal.
Trying to set global variable using 'local -g' is non-fatal.

In other cases, function is terminated immediately.

(BASH 5.0.16.)

$ declare -r VAR1=a
$ declare -ar VAR2=(a)
$ declare -Ar VAR3=([a]=a)
$ f() { local VAR1 VAR2 VAR3 ; echo AAA ; } ; f
bash: local: VAR1: readonly variable
bash: local: VAR2: readonly variable
bash: local: VAR3: readonly variable
AAA
$ f() { local VAR1=b VAR2=b VAR3=b ; echo AAA ; } ; f
bash: local: VAR1: readonly variable
bash: local: VAR2: readonly variable
bash: local: VAR3: readonly variable
AAA
$ f() { local -a VAR1 VAR2 VAR3 ; echo AAA ; } ; f
bash: local: VAR1: readonly variable
bash: local: VAR2: readonly variable
bash: local: VAR3: readonly variable
AAA
$ f() { local -a VAR1=(b) ; echo AAA ; } ; f
bash: f: VAR1: readonly variable
$ f() { local -a VAR2=(b) ; echo AAA ; } ; f
bash: f: VAR2: readonly variable
$ f() { local -a VAR3=(b) ; echo AAA ; } ; f
bash: f: VAR3: readonly variable
$ f() { local -A VAR1 VAR2 VAR3 ; echo AAA ; } ; f
bash: local: VAR1: readonly variable
bash: local: VAR2: readonly variable
bash: local: VAR3: readonly variable
AAA
$ f() { local -A VAR1=([b]=b) ; echo AAA ; } ; f
bash: f: VAR1: readonly variable
$ f() { local -A VAR2=([b]=b) ; echo AAA ; } ; f
bash: f: VAR2: readonly variable
$ f() { local -A VAR3=([b]=b) ; echo AAA ; } ; f
bash: f: VAR3: readonly variable
$ f() { local -g VAR1= VAR2= VAR3= ; echo AAA ; } ; f
bash: local: VAR1: readonly variable
bash: local: VAR2: readonly variable
bash: local: VAR3: readonly variable
AAA
$ f() { VAR1= ; echo AAA ; } ; f
bash: VAR1: readonly variable
$ f() { VAR2= ; echo AAA ; } ; f
bash: VAR2: readonly variable
$ f() { VAR3= ; echo AAA ; } ; f
bash: VAR3: readonly variable
$

--
Arfrever Frehtes Taifersar Arahesis



${variable@A} does not work for associative arrays

2020-02-19 Thread Arfrever Frehtes Taifersar Arahesis
BASH 5.0.16.

$ VAR1=aaa
$ declare -a VAR2=(aaa)
$ declare -A VAR3=([aaa]=aaa)
$ declare -p VAR{1,2,3}
declare -- VAR1="aaa"
declare -a VAR2=([0]="aaa")
declare -A VAR3=([aaa]="aaa" )
$ echo "${VAR1@A}"
VAR1='aaa'
$ echo "${VAR2@A}"
declare -a VAR2='aaa'
$ echo "${VAR3@A}"

$

--
Arfrever Frehtes Taifersar Arahesis



Assignments to FUNCNAME break FUNCNAME

2014-11-28 Thread Arfrever Frehtes Taifersar Arahesis
Manual of BASH claims:
Assignments to FUNCNAME have no effect and return an error status.

However assignments to FUNCNAME actually break FUNCNAME.
I use BASH 4.3.30.


Variant with local:

$ A() { echo A; declare -p FUNCNAME; local FUNCNAME=(); }
$ B() { echo B; declare -p FUNCNAME; }
$ A
A
declare -a FUNCNAME='([0]=A)'
bash: FUNCNAME: variable may not be assigned value
$ A
A
declare -a FUNCNAME='([0]=A [1]=A)'
bash: FUNCNAME: variable may not be assigned value
$ A
A
declare -a FUNCNAME='([0]=A [1]=A [2]=A)'
bash: FUNCNAME: variable may not be assigned value
$ B
B
declare -a FUNCNAME='([0]=B [1]=A [2]=A [3]=A)'
$ A
A
declare -a FUNCNAME='([0]=A [1]=A [2]=A [3]=A)'
bash: FUNCNAME: variable may not be assigned value
$ B
B
declare -a FUNCNAME='([0]=B [1]=A [2]=A [3]=A [4]=A)'
$ 


Variant without local:

$ A() { echo A; declare -p FUNCNAME; FUNCNAME=(); }
$ B() { echo B; declare -p FUNCNAME; }
$ A
A
declare -a FUNCNAME='([0]=A)'
$ A
A
declare -a FUNCNAME='([0]=A [1]=A)'
$ A
A
declare -a FUNCNAME='([0]=A [1]=A [2]=A)'
$ B
B
declare -a FUNCNAME='([0]=B [1]=A [2]=A [3]=A)'
$ A
A
declare -a FUNCNAME='([0]=A [1]=A [2]=A [3]=A)'
$ B
B
declare -a FUNCNAME='([0]=B [1]=A [2]=A [3]=A [4]=A)'
$ 


Also is it intentional that code after attempt of assignment to FUNCNAME is not 
run?
The sentence in manual could be interpreted as simply setting $? to non-zero 
value and still running subsequent code.

$ A() { echo A; local FUNCNAME=(); echo AAA; }   
$ A
A
bash: FUNCNAME: variable may not be assigned value
$

--
Arfrever Frehtes Taifersar Arahesis


signature.asc
Description: This is a digitally signed message part.


Re: REGRESSION: shellshock patch rejects valid function names

2014-09-27 Thread Arfrever Frehtes Taifersar Arahesis
2014-09-27 22:29 Eric Blake napisał(a):
 Thankfully, bash already forbids trying to name a function 'a=b'

It works in bash 4.3.26:

$ function a=b() { echo A; }
$ a=b
A
$ a\=b
A

--
Arfrever Frehtes Taifersar Arahesis


signature.asc
Description: This is a digitally signed message part.


Re: REGRESSION: shellshock patch rejects valid function names

2014-09-27 Thread Arfrever Frehtes Taifersar Arahesis
2014-09-27 23:12 Eric Blake napisał(a):
 On 09/27/2014 02:57 PM, Arfrever Frehtes Taifersar Arahesis wrote:
  2014-09-27 22:29 Eric Blake napisał(a):
  Thankfully, bash already forbids trying to name a function 'a=b'
  
  It works in bash 4.3.26:
  
  $ function a=b() { echo A; }
  $ a=b
  A
 
 Oh, you used the 'function' keyword, coupled with NOT quoting the name
 of the function.  I was trying to create the name via quotation:
 
 $ bash -c 'a\=b () { echo hi; }; a\=b'
 bash: `a\=b': not a valid identifier
 bash: a=b: command not found
 
 Still, since I strongly believe that import/export and valid function
 names should be the same set of characters, but that it would be
 extremely difficult to unambiguously encode = into environment variable
 function names, I think that we SHOULD take the step of forbidding '='
 in function names (the 'function' keyword should NOT be able to define
 any function that cannot also be defined in isolation, nor which cannot
 be imported from the environment using whatever improved implementation
 we decide for function export/import).

Ability to export/import functions with = in function names could be achieved 
by not embedding
function names in environmental variables and using a single BASH_FUNCTIONS 
environmental
variable whose value would contain code of all exported functions (in format 
similar to
`declare -fpx` / `export -fp`).

--
Arfrever Frehtes Taifersar Arahesis


signature.asc
Description: This is a digitally signed message part.


Re: 'local -x VARIABLE' does not clear variable for subprocesses

2014-05-05 Thread Arfrever Frehtes Taifersar Arahesis
2014-05-05 17:18 Chet Ramey napisał(a):
 On 5/3/14, 7:22 PM, Arfrever Frehtes Taifersar Arahesis wrote:
  'local -x VARIABLE' (without assignment of value) does not clear variable 
  for subprocesses.
  It is regression in bash 4.3.
 
 It's not actually a regression; it's a bug fix.  It's worth having the
 discussion again, though.
 
 A variable isn't set until it's assigned a value.  A statement like
 `local x' or `export x' doesn't actually create a variable.  It creates
 a `placeholder' so that a subsequent assignment will instantiate a
 variable with the right attributes, or change the behavior when a value
 is assigned, but does not assign a value itself.  This means that
 something like
 
 export x
 echo ${x-unset}
 printenv x
 
 will display `unset'.
 
 The idea behind the bash-4.3 behavior is that the placeholder local
 variable isn't set, and doesn't really exist.  It doesn't shadow a
 global variable with the same name until it gets a value.  The bash-4.2
 behavior was inconsistent: variables with attributes but without values
 weren't quite set (value == 0x0, but still visible) and weren't quite
 unset.

Behavior of bash 4.3 is inconsistent between non-subshell subprocesses and 
other places:

bash 4.2.47:

$ export VAR{1,2}=abc
$ f() { local VAR1; local -x VAR2; echo ### Normal scope:; declare -p 
VAR{1,2}; echo ### Subshell:; (declare -p VAR{1,2}); echo ### Non-subshell 
subprocess:; bash -c 'declare -p VAR{1,2}'; }
$ f
### Normal scope:
declare -x VAR1
declare -x VAR2
### Subshell:
declare -x VAR1
declare -x VAR2
### Non-subshell subprocess:
bash: line 0: declare: VAR1: not found
bash: line 0: declare: VAR2: not found

bash 4.3.11:

$ export VAR{1,2}=abc
$ f() { local VAR1; local -x VAR2; echo ### Normal scope:; declare -p 
VAR{1,2}; echo ### Subshell:; (declare -p VAR{1,2}); echo ### Non-subshell 
subprocess:; bash -c 'declare -p VAR{1,2}'; }
$ f
### Normal scope:
bash: declare: VAR1: not found
bash: declare: VAR2: not found
### Subshell:
bash: declare: VAR1: not found
bash: declare: VAR2: not found
### Non-subshell subprocess:
declare -x VAR1=abc
declare -x VAR2=abc


Ability to locally unset a variable also for subprocesses would be preferable 
solution.

--
Arfrever Frehtes Taifersar Arahesis


signature.asc
Description: This is a digitally signed message part.


Re: 'local -x VARIABLE' does not clear variable for subprocesses

2014-05-05 Thread Arfrever Frehtes Taifersar Arahesis
2014-05-05 22:12 Chet Ramey napisał(a):
  Ability to locally unset a variable also for subprocesses would be 
  preferable solution.
 
 OK.  I'm not sure exactly what this means.  Can you give me an example?
 How would you use this in a situation where `unset' or `declare +x' are
 unusable?

I would like to be able to unexport a variable for subprocesses called in given 
function, but
not subprocesses called later outside of given function.
Example of intended behavior (which happens to be behavior of bash 4.2):

$ export VAR=abc
$ f() { local -x VAR; bash -c 'declare -p VAR'; }
$ f
bash: line 0: declare: VAR: not found
$ bash -c 'declare -p VAR'
declare -x VAR=abc

Bare 'unset' also unexports a variable for subprocesses called later outside of 
given function
(both bash 4.2 and 4.3):

$ export VAR=abc
$ f() { unset VAR; bash -c 'declare -p VAR'; }
$ f
bash: line 0: declare: VAR: not found
$ bash -c 'declare -p VAR'
bash: line 0: declare: VAR: not found


'local' + 'unset' have effect on normal scope and subshells, but not on 
non-subshell subprocesses
(both bash 4.2 and 4.3):

bash 4.2:

$ export VAR{1,2,3,4}=aaa
$ f() { local VAR1 VAR2=bbb; local -x VAR3 VAR4=bbb; echo ## Before 
unsetting:; echo ### Normal scope:; declare -p VAR{1,2,3,4}; echo ### 
Subshell:; (declare -p VAR{1,2,3,4}); echo ### Non-subshell subprocess:; 
bash -c 'declare -p VAR{1,2,3,4}'; unset VAR{1,2,3,4}; echo ## After 
unsetting:; echo ### Normal scope:; declare -p VAR{1,2,3,4}; echo ### 
Subshell:; (declare -p VAR{1,2,3,4}); echo ### Non-subshell subprocess:; 
bash -c 'declare -p VAR{1,2,3,4}'; }
$ f
## Before unsetting:
### Normal scope:
declare -x VAR1
declare -x VAR2=bbb
declare -x VAR3
declare -x VAR4=bbb
### Subshell:
declare -x VAR1
declare -x VAR2=bbb
declare -x VAR3
declare -x VAR4=bbb
### Non-subshell subprocess:
bash: line 0: declare: VAR1: not found
declare -x VAR2=bbb
bash: line 0: declare: VAR3: not found
declare -x VAR4=bbb
## After unsetting:
### Normal scope:
bash: declare: VAR1: not found
bash: declare: VAR2: not found
bash: declare: VAR3: not found
bash: declare: VAR4: not found
### Subshell:
bash: declare: VAR1: not found
bash: declare: VAR2: not found
bash: declare: VAR3: not found
bash: declare: VAR4: not found
### Non-subshell subprocess:
declare -x VAR1=aaa
declare -x VAR2=aaa
declare -x VAR3=aaa
declare -x VAR4=aaa
$ bash -c 'declare -p VAR{1,2,3,4}'
declare -x VAR1=aaa
declare -x VAR2=aaa
declare -x VAR3=aaa
declare -x VAR4=aaa

bash 4.3:

$ export VAR{1,2,3,4}=aaa
$ f() { local VAR1 VAR2=bbb; local -x VAR3 VAR4=bbb; echo ## Before 
unsetting:; echo ### Normal scope:; declare -p VAR{1,2,3,4}; echo ### 
Subshell:; (declare -p VAR{1,2,3,4}); echo ### Non-subshell subprocess:; 
bash -c 'declare -p VAR{1,2,3,4}'; unset VAR{1,2,3,4}; echo ## After 
unsetting:; echo ### Normal scope:; declare -p VAR{1,2,3,4}; echo ### 
Subshell:; (declare -p VAR{1,2,3,4}); echo ### Non-subshell subprocess:; 
bash -c 'declare -p VAR{1,2,3,4}'; }
$ f
## Before unsetting:
### Normal scope:
bash: declare: VAR1: not found
declare -x VAR2=bbb
bash: declare: VAR3: not found
declare -x VAR4=bbb
### Subshell:
bash: declare: VAR1: not found
declare -x VAR2=bbb
bash: declare: VAR3: not found
declare -x VAR4=bbb
### Non-subshell subprocess:
declare -x VAR1=aaa
declare -x VAR2=bbb
declare -x VAR3=aaa
declare -x VAR4=bbb
## After unsetting:
### Normal scope:
bash: declare: VAR1: not found
bash: declare: VAR2: not found
bash: declare: VAR3: not found
bash: declare: VAR4: not found
### Subshell:
bash: declare: VAR1: not found
bash: declare: VAR2: not found
bash: declare: VAR3: not found
bash: declare: VAR4: not found
### Non-subshell subprocess:
declare -x VAR1=aaa
declare -x VAR2=aaa
declare -x VAR3=aaa
declare -x VAR4=aaa
$ bash -c 'declare -p VAR{1,2,3,4}'
declare -x VAR1=aaa
declare -x VAR2=aaa
declare -x VAR3=aaa
declare -x VAR4=aaa


'declare +x' (or 'local +x') fails to unexport a variable when called in a 
function (both bash 4.2 and 4.3):

$ export VAR=abc
$ f() { declare +x VAR; bash -c 'declare -p VAR'; }
$ f
declare -x VAR=abc
$ declare +x VAR
$ bash -c 'declare -p VAR'
bash: line 0: declare: VAR: not found

--
Arfrever Frehtes Taifersar Arahesis


signature.asc
Description: This is a digitally signed message part.


'local -x VARIABLE' does not clear variable for subprocesses

2014-05-03 Thread Arfrever Frehtes Taifersar Arahesis
'local -x VARIABLE' (without assignment of value) does not clear variable for 
subprocesses.
It is regression in bash 4.3.

Behavior of 'local VARIABLE' without -x option also changed, but I am not sure 
what should be correct
behavior in that case.

bash 4.2.47:

$ export VAR1=abc VAR2=abc
$ f() { local VAR1; local -x VAR2; bash -c 'declare -p VAR{1,2}'; }
$ f
bash: line 0: declare: VAR1: not found
bash: line 0: declare: VAR2: not found

bash 4.3.11:

$ export VAR1=abc VAR2=abc
$ f() { local VAR1; local -x VAR2; bash -c 'declare -p VAR{1,2}'; }
$ f
declare -x VAR1=abc
declare -x VAR2=abc

--
Arfrever Frehtes Taifersar Arahesis


signature.asc
Description: This is a digitally signed message part.


'declare +a -g' destroys local arrays

2013-08-22 Thread Arfrever Frehtes Taifersar Arahesis
I use bash 4.2.45.

`man bash` says:
Using `+' instead of `-' turns off the attribute instead, with the exceptions 
that +a may not be
used to destroy an array variable and +r will not remove the readonly 
attribute.

However 'declare +a -g' destroys local arrays, which do not shadow global 
arrays:

$ f() { local ARRAY=(a b c); declare -p ARRAY; declare +a -g ARRAY; declare -p 
ARRAY; }
$ f
declare -a ARRAY='([0]=a [1]=b [2]=c)'
bash: declare: ARRAY: cannot destroy array variables in this way
bash: declare: ARRAY: not found
$ ARRAY=(x y z)
$ f
declare -a ARRAY='([0]=a [1]=b [2]=c)'
bash: declare: ARRAY: cannot destroy array variables in this way
declare -a ARRAY='([0]=a [1]=b [2]=c)'

--
Arfrever Frehtes Taifersar Arahesis


signature.asc
Description: This is a digitally signed message part.


Subsequent `declare -fp` and `.` incorrectly restore function with here string with pattern substitution

2010-01-24 Thread Arfrever Frehtes Taifersar Arahesis
Configuration Information:
Machine: x86_64
OS: linux-gnu
Compiler: x86_64-pc-linux-gnu-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  
-DDEFAULT_PATH_VALUE='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
 -DSTANDARD_UTILS_PATH='/bin:/usr/bin:/sbin:/usr/sbin' 
-DSYS_BASHRC='/etc/bash/bashrc' -DSYS_BASH_LOGOUT='/etc/bash/bash_logout' 
-DNON_INTERACTIVE_LOGIN_SHELLS -DSSH_SOURCE_BASHRC -march=core2 -O2 -pipe
Machine Type: x86_64-pc-linux-gnu

Bash Version: 4.0
Patch Level: 37
Release Status: release

Description:
Subsequent `declare -fp` and `.` incorrectly restore function with here 
string with pattern substitution.

Repeat-By:
The following function is incorrectly restored:
here_string_test() {
:  ${var// /$'\n'}
}

Run the attached bash_test.sh script using this command:
env -i bash_test.sh

-- 
Arfrever Frehtes Taifersar Arahesis


bash_test.sh
Description: application/shellscript


signature.asc
Description: This is a digitally signed message part.