bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Dynamic variable failure & equiv-const strings compare unequal


From: Oleg Popov
Subject: Re: Dynamic variable failure & equiv-const strings compare unequal
Date: Thu, 22 Oct 2015 13:58:16 +0300

On Thu, Oct 22, 2015 at 03:01:06AM -0700, Linda Walsh wrote:
> [cut]
> I.e. test output was:
> Case 2 got/Expected:
> "222"
> "1\ 222\ .3\ .4"
> [cut]

You didn't initialize the array. By the time you do "parts[1]=222" it's 
still empty. And in your previous message you tried to initialize it in 
a subshell. Variables don't retain their values after returning from 
subshells.

> [cut]
> test 3 --- was supposed to check the values
> of the hash field-by-field, but first I thought to check
> them when printed out in a specific order as 2 identical
> strings.  The strings look identical, yet don't compare equal.
> so it seemed pointless to try to break down test 3's output
> into a field-by-field comparison when I couldn't even get
> the identical strings that contained the fields to compare.
> [cut]

> [cut]
>    if [[ $out != $exp ]]; then
> [cut]

Bash uses unquoted characters on the right side of == and != as wildcard 
patterns. For example, [ipaddr] in $exp means "any of i, p, a, d, r".  
You should quote the right operand.


> #!/bin/bash
> 
> shopt -s expand_aliases ; alias my=declare
> alias array='my -a' int='my -i'
> 
> ip=10.20.30.40
> array  parts=()  
> array answers=(  '10 20 30 40'   '1 .2 .3 .4'  '1 222 .3 .4' 
> '192.168.0.1/24::{ [ipaddr]="192.168.0.1/24" [address]="192.168.0.1" 
> [prefixlen]="24" ; }'
> )
> 
> 
> array addr_fields=(ipaddr address prefixlen)
>                 
> assignparts() { parts=( $ip ) ; }
> 
> tst0 () { my IFS=. ; assignparts ; echo -E "${parts[@]}"; }
> tst1 () { my IFS=0 ; assignparts ; echo -E "${parts[@]}"; }
> tst2 () { parts[1]=222; echo -E "${parts[@]}" ; }
> 
> tst3 () {
>  my ipaddr="$1"; shift;
>  int status=0
>  my pat='^([^/]+)/([0-9]+)\s*$'
>  my address prefixlen
>  if [[ ! $ipaddr =~ $pat ]]; then
>    echo >&2 "Error in ip/netsize format: \"$ipaddr\""
>    status=1
>  else
>    address=${BASH_REMATCH[1]}
>    prefixlen=${BASH_REMATCH[2]}
>    my out=""
>    for flds in "${addr_fields[@]}"; do
>      out+="[$flds]=\"${!flds}\" "
>    done
>    printf "{ %s; }" "$out"
>  fi
>  return $status
> }
> 
> 
> 
> int passno=0 tests=0
> my fmt="Case %d got/Expected:\n \"%q\"\n \"%q\"\n"
> 
> 
> testor () {
>  int tstno
>  my out=""
>  for tstno in {0..3}; do
>    tests+=1
>    exp="${answers[tstno]}"
>    if [[ $exp =~ :: ]]; then
>      my args="${exp%::*}"
>      exp="${exp#*::}"
>      out="$(tst$tstno $args)"
>    else
>      out="$(tst$tstno)"
>    fi
>    if [[ $out != $exp ]]; then
>      printf >&2 "$fmt" "$tstno" "$out" "$exp"
>      continue
>    fi
>    passno+=1
>  done
> }
> 
> testor
> echo "Passed $passno/$tests tests."
> ----------------
> 
> output:
> Case 2 got/Expected:
> "222"
> "1\ 222\ .3\ .4"
> Case 3 got/Expected:
> "\{\ \[ipaddr\]=\"192.168.0.1/24\"\ \[address\]=\"192.168.0.1\"\ 
> \[prefixlen\]=\"24\"\ \;\ \}"
> "\{\ \[ipaddr\]=\"192.168.0.1/24\"\ \[address\]=\"192.168.0.1\"\ 
> \[prefixlen\]=\"24\"\ \;\ \}"
> Passed 2/4 tests.
> 
> The outputs for case 3 look identical -- I was using %s to print
> them out, but switched to "%q", to ensure no hidden chars...
> 
> case 2 --
> ???  Why didn't it only change the 1 member?
> 
> 
> 
> 
> 
> 
> 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]