Score:0

Running the same code with -u and +u gives different results

cn flag

I have a fairly large set of scripts that is the initial part of creating some debug/logging logic for bash scripts. There is a considerable amount of code in the system. Fortunately I can demonstrate the different results that I cannot explain when the script is run +u and -u. Set variables as tested using +u become unset variables when run with -u. The variabl.e name in this case is $FUNCNAME

The short test script are as follows:

#!/bin/bash


### set     -e
### set     -f
### set     -u
### set     -C
### set     -P
### set     -o  pipefail


export  PS4='+:${BASH_SOURCE[0]}:${FUNCNAME[0]}:${LINENO[0]}::x::   '


set     -o  verbose

    #   vXtrap Field Separator  u0081 (plus/minus)
### export  vXtrapLFS='\v'

    #   replacement BASH_SUBSHELL
export  vXtrapSub=()

    #   replacement BASH_SOURCE
export  vXtrapSrc=()

    #   replacement Script
    #       basename "${vXtrapSub[$lIdx]}}" '.sh'
export  vXtrapScr=()

    #   replacement FUNCNAME
export  vXtrapFNm=()

    #   replacement LINENO 
    #       where BASH_LINENO[lIdx] should equal vXtrapLNo[lIdx+1]
export  vXtrapLNo=()

    #   LINENO initiation
    #       line number initial report of function in Debug Trap
export  vXtrapLNI=()

    #   replacement BASH_COMMAND
    #       this is the original unsubstituted source command
    #   the following is a compressed substituted version of the source command
    #       "${vXtrcTrapArg0[$lIdx]} ${vXtrcTrapArgV[$lIdx]}"
export vXtrapCmd=()

    #   replacement BASH_ARGV0
export  vXtrapArg0=()

    #   replacement BASH_ARGVC
export  vXtrapArgC=()

#   replacement BASH_ARGV
#       space delimited
export  vXtrapArgV=()

    #   replacement $?
export  vXtrapRc=()

    #   replacement syserr message
export  vXtrapRcMsg=()

set     +o  verbose

read -rp '090'

#####
#       Transfer Initial command initiation to the revised trace table
#####

i=0
iMax=${#BASH_LINENO[@]}
j=0
k=0
v=''

printf '\n'
v="$BASH_SUBSHELL"
if [[ -z "$v" && -n "${v-_}" ]]; then
    echo '$BASH_SUBSHELL      unset    '"$BASH_SUBSHELL"
else
    echo '$BASH_SUBSHELL      set      '"$BASH_SUBSHELL"
fi

v="$LINENO"
if [[ -z "$v" && -n "${v-_}" ]]; then
    echo '$LINENO             unset    '"$LINENO"
else
    echo '$LINENO             set      '"$LINENO"
fi

v="$BASH_COMMAND"
if [[ -z "$v" && -n "${v-_}" ]]; then
    echo '$BASH_COMMAND       unset    '"$BASH_COMMAND"
else
    echo '$BASH_COMMAND       set      '"$BASH_COMMAND"
fi

for (( i=0; i<=iMax;    i++ ))
do
    printf '\n'

    v="${BASH_SOURCE["$i"]}"
    if [[ -z "$v" && -n "${v-_}" ]]; then
        echo '${BASH_SOURCE['"$i"']}   unset    '"${BASH_SOURCE[$i]}"
    else
        echo '${BASH_SOURCE['"$i"']}   set      '"${BASH_SOURCE[$i]}"
    fi

    v="${FUNCNAME[$i]}"
    if [[ -z "$v" && -n "${v-_}" ]]; then
        echo '${FUNCNAME['"$i"']}      unset    '"${FUNCNAME[$i]}"
    else
        echo '${FUNCNAME['"$i"']}      set      '"${FUNCNAME[$i]}"
    fi

    v="${BASH_LINENO["$i"]}"
    if [[ -z "$v" && -n "${v-_}" ]]; then
        echo '${BASH_LINENO['"$i"']}   unset    '"${BASH_LINENO[$i]}"
    else
        echo '${BASH_LINENO['"$i"']}   set      '"${BASH_LINENO[$i]}"
    fi

    v="${BASH_ARGV0[i]}"
    if [[ -z "$v" && -n "${v-_}" ]]; then
        echo '${BASH_ARGV0['"$i"']}    unset    '"${BASH_ARGV0[$i]}"
    else
        echo '${BASH_ARGV0['"$i"']}    set      '"${BASH_ARGV0[$i]}"
    fi

    v="${BASH_ARGC[i]}"
    if [[ -z "$v" && -n "${v-_}" ]]; then
        echo '${BASH_ARGC['"$i"']}     unset    '"${BASH_ARGC[$i]}"
    else
        echo '${BASH_ARGC['"$i"']}     set      '"${BASH_ARGC[$i]}"
    fi

    j=0
    while [ "$j" -lt "${BASH_ARGC[i]}" ]
    do

        v="${BASH_ARGV["$k"]}"
        if [[ -z "$v" && -n "${v-_}" ]]; then
            echo '${BASH_ARGV['"$i $j"']}   unset  ref=${BASH_ARGV['"$k"']}    '"${BASH_ARGV["$k"]}"
        else
            echo '${BASH_ARGV['"$i $j"']}   set    ref=${BASH_ARGV['"$k"']}    '"${BASH_ARGV["$k"]}"
        fi
        (( k++ ))
        (( j++ ))
    done
done

vPtrapScr="$(basename "${BASH_SOURCE[0]}" '.sh' )"

vPtrapArgC='1'
vPtrapArgV=''
while [ $vPtrapArgC -lt ${BASH_ARGC[0]} ]
do
    case "$vPtrapArgC"  in
        (0)
            vPtrapArgV=" \"${BASH_ARGV["vPtrapArgC"]}\""
            ;;

        (*)
            vPtrapArgV=" \"${BASH_ARGV["$vPtrapArgC"]}\"$vPtrapArgV"
            ;;
    esac


    (( vPtrapArgC++ ))
done

    #   Don't know why FUNCNAME[0] after new terminal is 
    #       '' instead of 'source'
### vPtrapArg0="${FUNCNAME[0]}"
vPtrapArg0='source'

vPtrapCmd="source \"${BASH_SOURCE[0]}\" ${vPtrapArgV}"

vPtrapArgV="\"${BASH_SOURCE[0]}\" ${vPtrapArgV}"

set     -o  xtrace

vXtrapSub=(     "$BASH_SUBSHELL" "$BASH_SUBSHELL"   "$BASH_SUBSHELL" )
vXtrapSrc=(  "${BASH_SOURCE[0]}" ''                  ''              )
vXtrapScr=(         "$vPtrapScr" ''                  ''              )
vXtrapFNm=(                   '' ''                  ''              )
vXtrapLNo=(                  '0' "${BASH_LINENO[0]}" '0'             )
vXtrapLNI=(                  '0' '0'                 '0'             )
    #   values below this line are currently for the calling instruction
    #       when the DEBUG trap activates these will be current script instruction
vXtrapCmd=(        "$vPtrapCmd" "$vPtrapCmd"         ''              )
vXtrapArg0=(      "$vPtrapArg0" "$vPtrapArg0"        ''              )
vXtrapArgC=(      "$vPtrapArgC" "$vPtrapArgC"        '0'             )
vXtrapArgV=(      "$vPtrapArgV" "$vPtrapArgV"        ''              )
vXtrapRc=(                  '0' '0'                  '0'             )
vXtrapRcMsg=(                '' ''                   ''              )

set     +o  xtrace

read -rp '100'

unset   i
unset   iMax
unset   j
unset   k
unset   v
unset   vPtrapScr
unset   vPtrapCmd
unset   vPtrapArg0
unset   vPtrapArgC
unset   vPtrapArgV

read -rp '110'


return  "${vXtrapRc[0]}"


The first run +u has set variables those same variables become unset (specifically $FUNCNAME that prevents the many of the others from being tested) in the -u run.
The test output:

ubuntu@ubuntu:/$ set +u
ubuntu@ubuntu:/$ cd /pool/src/trap/scr
ubuntu@ubuntu:/pool/src/trap/scr$ source SHtest.sh

        #       vXtrap Field Separator  u0081 (plus/minus)
###     export  vXtrapLFS='\v'

        #       replacement BASH_SUBSHELL
export  vXtrapSub=()

        #       replacement BASH_SOURCE
export  vXtrapSrc=()

        #       replacement Script
        #               basename "${vXtrapSub[$lIdx]}}" '.sh'
export  vXtrapScr=()

        #       replacement FUNCNAME
export  vXtrapFNm=()

        #       replacement LINENO 
        #               where BASH_LINENO[lIdx] should equal vXtrapLNo[lIdx+1]
export  vXtrapLNo=()

        #       LINENO initiation
        #               line number initial report of function in Debug Trap
export  vXtrapLNI=()

        #       replacement BASH_COMMAND
        #               this is the original unsubstituted source command
        #       the following is a compressed substituted version of the source command
        #               "${vXtrcTrapArg0[$lIdx]} ${vXtrcTrapArgV[$lIdx]}"
export vXtrapCmd=()

        #       replacement BASH_ARGV0
export  vXtrapArg0=()

        #       replacement BASH_ARGVC
export  vXtrapArgC=()

#       replacement BASH_ARGV
#               space delimited
export  vXtrapArgV=()

        #       replacement $?
export  vXtrapRc=()

        #       replacement syserr message
export  vXtrapRcMsg=()

set             +o      verbose
090

$BASH_SUBSHELL      set      0
$LINENO             set      89
$BASH_COMMAND       set      echo '$BASH_COMMAND       set      '"$BASH_COMMAND"

${BASH_SOURCE[0]}   set      SHtest.sh
${FUNCNAME[0]}      set      
${BASH_LINENO[0]}   set      3
${BASH_ARGV0[0]}    set      /usr/bin/bash
${BASH_ARGC[0]}     set      1
${BASH_ARGV[0 0]}   set    ref=${BASH_ARGV[0]}    SHtest.sh

${BASH_SOURCE[1]}   set      
${FUNCNAME[1]}      set      
${BASH_LINENO[1]}   set      
${BASH_ARGV0[1]}    set      
${BASH_ARGC[1]}     set      0
++:SHtest.sh::184::x::  vXtrapSub=("$BASH_SUBSHELL" "$BASH_SUBSHELL" "$BASH_SUBSHELL")
++:SHtest.sh::185::x::  vXtrapSrc=("${BASH_SOURCE[0]}" '' '')
++:SHtest.sh::186::x::  vXtrapScr=("$vPtrapScr" '' '')
++:SHtest.sh::187::x::  vXtrapFNm=('' '' '')
++:SHtest.sh::188::x::  vXtrapLNo=('0' "${BASH_LINENO[0]}" '0')
++:SHtest.sh::189::x::  vXtrapLNI=('0' '0' '0')
++:SHtest.sh::192::x::  vXtrapCmd=("$vPtrapCmd" "$vPtrapCmd" '')
++:SHtest.sh::193::x::  vXtrapArg0=("$vPtrapArg0" "$vPtrapArg0" '')
++:SHtest.sh::194::x::  vXtrapArgC=("$vPtrapArgC" "$vPtrapArgC" '0')
++:SHtest.sh::195::x::  vXtrapArgV=("$vPtrapArgV" "$vPtrapArgV" '')
++:SHtest.sh::196::x::  vXtrapRc=('0' '0' '0')
++:SHtest.sh::197::x::  vXtrapRcMsg=('' '' '')
++:SHtest.sh::199::x::  set +o xtrace
100
110
ubuntu@ubuntu:/pool/src/trap/scr$ set -u
ubuntu@ubuntu:/pool/src/trap/scr$ source SHtest.sh

        #       vXtrap Field Separator  u0081 (plus/minus)
###     export  vXtrapLFS='\v'

        #       replacement BASH_SUBSHELL
export  vXtrapSub=()

        #       replacement BASH_SOURCE
export  vXtrapSrc=()

        #       replacement Script
        #               basename "${vXtrapSub[$lIdx]}}" '.sh'
export  vXtrapScr=()

        #       replacement FUNCNAME
export  vXtrapFNm=()

        #       replacement LINENO 
        #               where BASH_LINENO[lIdx] should equal vXtrapLNo[lIdx+1]
export  vXtrapLNo=()

        #       LINENO initiation
        #               line number initial report of function in Debug Trap
export  vXtrapLNI=()

        #       replacement BASH_COMMAND
        #               this is the original unsubstituted source command
        #       the following is a compressed substituted version of the source command
        #               "${vXtrcTrapArg0[$lIdx]} ${vXtrcTrapArgV[$lIdx]}"
export vXtrapCmd=()

        #       replacement BASH_ARGV0
export  vXtrapArg0=()

        #       replacement BASH_ARGVC
export  vXtrapArgC=()

#       replacement BASH_ARGV
#               space delimited
export  vXtrapArgV=()

        #       replacement $?
export  vXtrapRc=()

        #       replacement syserr message
export  vXtrapRcMsg=()

set             +o      verbose
090

$BASH_SUBSHELL      set      0
$LINENO             set      89
$BASH_COMMAND       set      echo '$BASH_COMMAND       set      '"$BASH_COMMAND"

${BASH_SOURCE[0]}   set      SHtest.sh
bash: FUNCNAME[$i]: unbound variable
bash: FUNCNAME[0]: unbound variable
++:${BASH_SOURCE[0]}:${FUNCNAME[0]}:${LINENO[0]}::x::   vXtrapSub=("$BASH_SUBSHELL" "$BASH_SUBSHELL" "$BASH_SUBSHELL")
bash: FUNCNAME[0]: unbound variable
++:${BASH_SOURCE[0]}:${FUNCNAME[0]}:${LINENO[0]}::x::   vXtrapSrc=("${BASH_SOURCE[0]}" '' '')
bash: FUNCNAME[0]: unbound variable
++:${BASH_SOURCE[0]}:${FUNCNAME[0]}:${LINENO[0]}::x::   vXtrapScr=("$vPtrapScr" '' '')
bash: FUNCNAME[0]: unbound variable
++:${BASH_SOURCE[0]}:${FUNCNAME[0]}:${LINENO[0]}::x::   vXtrapFNm=('' '' '')
bash: FUNCNAME[0]: unbound variable
++:${BASH_SOURCE[0]}:${FUNCNAME[0]}:${LINENO[0]}::x::   vXtrapLNo=('0' "${BASH_LINENO[0]}" '0')
bash: FUNCNAME[0]: unbound variable
++:${BASH_SOURCE[0]}:${FUNCNAME[0]}:${LINENO[0]}::x::   vXtrapLNI=('0' '0' '0')
bash: FUNCNAME[0]: unbound variable
++:${BASH_SOURCE[0]}:${FUNCNAME[0]}:${LINENO[0]}::x::   vXtrapCmd=("$vPtrapCmd" "$vPtrapCmd" '')
bash: FUNCNAME[0]: unbound variable
++:${BASH_SOURCE[0]}:${FUNCNAME[0]}:${LINENO[0]}::x::   vXtrapArg0=("$vPtrapArg0" "$vPtrapArg0" '')
bash: FUNCNAME[0]: unbound variable
++:${BASH_SOURCE[0]}:${FUNCNAME[0]}:${LINENO[0]}::x::   vXtrapArgC=("$vPtrapArgC" "$vPtrapArgC" '0')
bash: FUNCNAME[0]: unbound variable
++:${BASH_SOURCE[0]}:${FUNCNAME[0]}:${LINENO[0]}::x::   vXtrapArgV=("$vPtrapArgV" "$vPtrapArgV" '')
bash: FUNCNAME[0]: unbound variable
++:${BASH_SOURCE[0]}:${FUNCNAME[0]}:${LINENO[0]}::x::   vXtrapRc=('0' '0' '0')
bash: FUNCNAME[0]: unbound variable
++:${BASH_SOURCE[0]}:${FUNCNAME[0]}:${LINENO[0]}::x::   vXtrapRcMsg=('' '' '')
bash: FUNCNAME[0]: unbound variable
++:${BASH_SOURCE[0]}:${FUNCNAME[0]}:${LINENO[0]}::x::   set +o xtrace
100
110
ubuntu@ubuntu:/pool/src/trap/scr$

I hope this code and output makes sense to those that read it.

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.