Рейтинг:0

Запуск одного и того же кода с -u и +u дает разные результаты

флаг cn

У меня есть довольно большой набор сценариев, которые являются начальной частью создания некоторой логики отладки/регистрации для сценариев bash. В системе имеется значительное количество кода. К счастью, я могу продемонстрировать различные результаты, которые я не могу объяснить, когда скрипт запускает +u и -u. Установить переменные как проверенные с помощью +u, которые становятся неустановленными переменными при запуске с -u. Имя переменной в этом случае $FUNCNAME.

Краткий тестовый сценарий выглядит следующим образом:

#!/бин/баш


### установить -e
### установить -f
### установить -у
### установить -C
### установить -P
### set -o pipefail


экспорт PS4='+:${BASH_SOURCE[0]}:${FUNCNAME[0]}:${LINENO[0]}::x:: '


установить -o подробный

    # Разделитель полей vXtrap u0081 (плюс/минус)
### экспорт vXtrapLFS='\v'

    # замена BASH_SUBSHELL
экспортировать vXtrapSub=()

    # замена BASH_SOURCE
экспортировать vXtrapSrc=()

    # скрипт замены
    # базовое имя "${vXtrapSub[$lIdx]}}" '.sh'
экспортировать vXtrapScr=()

    # замена FUNCNAME
экспортировать vXtrapFNm=()

    # замена ЛИНЕНО 
    # где BASH_LINENO[lIdx] должен равняться vXtrapLNo[lIdx+1]
экспортировать vXtrapLNo=()

    # LINENO инициация
    # номер строки начального отчета функции в ловушке отладки
экспортировать vXtrapLNI=()

    # замена BASH_COMMAND
    # это исходная незамещенная исходная команда
    # ниже приведена сжатая версия исходной команды с заменой
    # "${vXtrcTrapArg0[$lIdx]} ${vXtrcTrapArgV[$lIdx]}"
экспортировать vXtrapCmd=()

    # замена BASH_ARGV0
экспортировать vXtrapArg0=()

    # замена BASH_ARGVC
экспортировать vXtrapArgC=()

# замена BASH_ARGV
# разделен пробелом
экспортировать vXtrapArgV=()

    # замена $?
экспортировать vXtrapRc=()

    # замена сообщения syserr
экспортировать vXtrapRcMsg=()

установить +o подробный

читать -рп '090'

#####
# Передача инициализации начальной команды в исправленную таблицу трассировки
#####

я=0
iMax=${#BASH_LINENO[@]}
j=0
к=0
v=''

напечатать '\n'
v="$BASH_SUBSHELL"
если [[ -z "$v" && -n "${v-_}" ]]; тогда
    echo '$BASH_SUBSHELL не установлен '"$BASH_SUBSHELL"
еще
    echo '$BASH_SUBSHELL установить '"$BASH_SUBSHELL"
фи

v="$LINENO"
если [[ -z "$v" && -n "${v-_}" ]]; тогда
    echo '$LINENO отключено'"$LINENO"
еще
    echo '$LINENO установить '"$LINENO"
фи

v="$BASH_КОМАНДА"
если [[ -z "$v" && -n "${v-_}" ]]; тогда
    эхо '$ BASH_COMMAND отключено '"$ BASH_COMMAND"
еще
    echo '$BASH_COMMAND установить '"$BASH_COMMAND"
фи

для (( я = 0; я <= iMax; я ++ ))
делать
    напечатать '\n'

    v="${BASH_SOURCE["$i"]}"
    если [[ -z "$v" && -n "${v-_}" ]]; тогда
        echo '${BASH_SOURCE['"$i"']} отключено '"${BASH_SOURCE[$i]}"
    еще
        echo '${BASH_SOURCE['"$i"']} установить '"${BASH_SOURCE[$i]}"
    фи

    v="${ИМЯ_ФУНКЦИИ[$i]}"
    если [[ -z "$v" && -n "${v-_}" ]]; тогда
        echo '${FUNCNAME['"$i"']} снято '"${FUNCNAME[$i]}"
    еще
        echo '${FUNCNAME['"$i"']} установить '"${FUNCNAME[$i]}"
    фи

    v="${BASH_LINENO["$i"]}"
    если [[ -z "$v" && -n "${v-_}" ]]; тогда
        echo '${BASH_LINENO['"$i"']} отключено '"${BASH_LINENO[$i]}"
    еще
        echo '${BASH_LINENO['"$i"']} установить '"${BASH_LINENO[$i]}"
    фи

    v="${BASH_ARGV0[i]}"
    если [[ -z "$v" && -n "${v-_}" ]]; тогда
        echo '${BASH_ARGV0['"$i"']} снято '"${BASH_ARGV0[$i]}"
    еще
        echo '${BASH_ARGV0['"$i"']} установить '"${BASH_ARGV0[$i]}"
    фи

    v="${BASH_ARGC[i]}"
    если [[ -z "$v" && -n "${v-_}" ]]; тогда
        echo '${BASH_ARGC['"$i"']} снято '"${BASH_ARGC[$i]}"
    еще
        echo '${BASH_ARGC['"$i"']} установить '"${BASH_ARGC[$i]}"
    фи

    j=0
    в то время как ["$j" -lt "${BASH_ARGC[i]}"]
    делать

        v="${BASH_ARGV["$k"]}"
        если [[ -z "$v" && -n "${v-_}" ]]; тогда
            echo '${BASH_ARGV['"$i $j"']} unset ref=${BASH_ARGV['"$k"']} '"${BASH_ARGV["$k"]}"
        еще
            echo '${BASH_ARGV['"$i $j"']} set ref=${BASH_ARGV['"$k"']} '"${BASH_ARGV["$k"]}"
        фи
        ((к++))
        (( j++ ))
    сделано
сделано

vPtrapScr="$(базовое имя "${BASH_SOURCE[0]}" '.sh' )"

vPtrapArgC='1'
vPtrapArgV=''
в то время как [$vPtrapArgC -lt ${BASH_ARGC[0]}]
делать
    case "$vPtrapArgC" в
        (0)
            vPtrapArgV=" \"${BASH_ARGV["vPtrapArgC"]}\""
            ;;

        (*)
            vPtrapArgV=" \"${BASH_ARGV["$vPtrapArgC"]}\"$vPtrapArgV"
            ;;
    эсак


    (( vPtrapArgC++ ))
сделано

    # Не знаю, почему FUNCNAME[0] после нового терминала 
    # '' вместо 'источник'
### vPtrapArg0="${FUNCNAME[0]}"
vPtrapArg0='источник'

vPtrapCmd="источник \"${BASH_SOURCE[0]}\" ${vPtrapArgV}"

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

установить -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' )
    # значения ниже этой строки в настоящее время относятся к вызывающей инструкции
    # когда активируется ловушка DEBUG, это будет текущая инструкция скрипта
vXtrapCmd=( "$vPtrapCmd" "$vPtrapCmd" '' )
vXtrapArg0=( "$vPtrapArg0" "$vPtrapArg0" '' )
vXtrapArgC=( "$vPtrapArgC" "$vPtrapArgC" '0' )
vXtrapArgV=( "$vPtrapArgV" "$vPtrapArgV" '' )
vXtrapRc=( '0' '0' '0' )
vXtrapRcMsg=( '' '' '' )

установить +o xtrace

читать -рп '100'

отключить я
отключить iMax
сбросить j
сбросить k
снято v
сбросить vPtrapScr
отключить vPtrapCmd
сбросить vPtrapArg0
сбросить vPtrapArgC
сбросить vPtrapArgV

читать -рп '110'


вернуть "${vXtrapRc[0]}"


Первый запуск +u установил переменные, те же самые переменные становятся неустановленными (в частности, $FUNCNAME, которая предотвращает тестирование многих других) при запуске -u.
Вывод теста:

ubuntu@ubuntu:/$ установить +u
ubuntu@ubuntu:/$ cd /pool/src/trap/scr
ubuntu@ubuntu:/pool/src/trap/scr$ источник SHtest.sh

        # Разделитель полей vXtrap u0081 (плюс/минус)
### экспорт vXtrapLFS='\v'

        # замена BASH_SUBSHELL
экспортировать vXtrapSub=()

        # замена BASH_SOURCE
экспортировать vXtrapSrc=()

        # скрипт замены
        # базовое имя "${vXtrapSub[$lIdx]}}" '.sh'
экспортировать vXtrapScr=()

        # замена FUNCNAME
экспортировать vXtrapFNm=()

        # замена ЛИНЕНО 
        # где BASH_LINENO[lIdx] должен равняться vXtrapLNo[lIdx+1]
экспортировать vXtrapLNo=()

        # LINENO инициация
        # номер строки начального отчета функции в ловушке отладки
экспортировать vXtrapLNI=()

        # замена BASH_COMMAND
        # это исходная незамещенная исходная команда
        # ниже приведена сжатая версия исходной команды с заменой
        # "${vXtrcTrapArg0[$lIdx]} ${vXtrcTrapArgV[$lIdx]}"
экспортировать vXtrapCmd=()

        # замена BASH_ARGV0
экспортировать vXtrapArg0=()

        # замена BASH_ARGVC
экспортировать vXtrapArgC=()

# замена BASH_ARGV
# разделен пробелом
экспортировать vXtrapArgV=()

        # замена $?
экспортировать vXtrapRc=()

        # замена сообщения syserr
экспортировать vXtrapRcMsg=()

установить +o подробный
090

$BASH_SUBSHELL установить 0
$LINENO набор 89
$BASH_COMMAND установить эхо '$BASH_COMMAND установить '"$BASH_COMMAND"

${BASH_SOURCE[0]} задал SHtest.sh
Набор ${FUNCNAME[0]}      
${BASH_LINENO[0]} набор 3
${BASH_ARGV0[0]} установить /usr/bin/bash
${BASH_ARGC[0]} установить 1
${BASH_ARGV[0 0]} установить ссылку=${BASH_ARGV[0]} SHtest.sh

Набор ${BASH_SOURCE[1]}      
Набор ${FUNCNAME[1]}      
Набор ${BASH_LINENO[1]}      
Набор ${BASH_ARGV0[1]}      
${BASH_ARGC[1]} установить 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$ установить -u
ubuntu@ubuntu:/pool/src/trap/scr$ источник SHtest.sh

        # Разделитель полей vXtrap u0081 (плюс/минус)
### экспорт vXtrapLFS='\v'

        # замена BASH_SUBSHELL
экспортировать vXtrapSub=()

        # замена BASH_SOURCE
экспортировать vXtrapSrc=()

        # скрипт замены
        # базовое имя "${vXtrapSub[$lIdx]}}" '.sh'
экспортировать vXtrapScr=()

        # замена FUNCNAME
экспортировать vXtrapFNm=()

        # замена ЛИНЕНО 
        # где BASH_LINENO[lIdx] должен равняться vXtrapLNo[lIdx+1]
экспортировать vXtrapLNo=()

        # LINENO инициация
        # номер строки начального отчета функции в ловушке отладки
экспортировать vXtrapLNI=()

        # замена BASH_COMMAND
        # это исходная незамещенная исходная команда
        # ниже приведена сжатая версия исходной команды с заменой
        # "${vXtrcTrapArg0[$lIdx]} ${vXtrcTrapArgV[$lIdx]}"
экспортировать vXtrapCmd=()

        # замена BASH_ARGV0
экспортировать vXtrapArg0=()

        # замена BASH_ARGVC
экспортировать vXtrapArgC=()

# замена BASH_ARGV
# разделен пробелом
экспортировать vXtrapArgV=()

        # замена $?
экспортировать vXtrapRc=()

        # замена сообщения syserr
экспортировать vXtrapRcMsg=()

установить +o подробный
090

$BASH_SUBSHELL установить 0
$LINENO набор 89
$BASH_COMMAND установить эхо '$BASH_COMMAND установить '"$BASH_COMMAND"

${BASH_SOURCE[0]} задал SHtest.sh
bash: FUNCNAME[$i]: несвязанная переменная
bash: FUNCNAME[0]: несвязанная переменная
++:${BASH_SOURCE[0]}:${FUNCNAME[0]}:${LINENO[0]}::x:: vXtrapSub=("$BASH_SUBSHELL" "$BASH_SUBSHELL" "$BASH_SUBSHELL")
bash: FUNCNAME[0]: несвязанная переменная
++:${BASH_SOURCE[0]}:${FUNCNAME[0]}:${LINENO[0]}::x:: vXtrapSrc=("${BASH_SOURCE[0]}" '' '')
bash: FUNCNAME[0]: несвязанная переменная
++:${BASH_SOURCE[0]}:${FUNCNAME[0]}:${LINENO[0]}::x:: vXtrapScr=("$vPtrapScr" '' '')
bash: FUNCNAME[0]: несвязанная переменная
++:${BASH_SOURCE[0]}:${FUNCNAME[0]}:${LINENO[0]}::x:: vXtrapFNm=('' '' '')
bash: FUNCNAME[0]: несвязанная переменная
++:${BASH_SOURCE[0]}:${FUNCNAME[0]}:${LINENO[0]}::x:: vXtrapLNo=('0' "${BASH_LINENO[0]}" '0')
bash: FUNCNAME[0]: несвязанная переменная
++:${BASH_SOURCE[0]}:${FUNCNAME[0]}:${LINENO[0]}::x:: vXtrapLNI=('0' '0' '0')
bash: FUNCNAME[0]: несвязанная переменная
++:${BASH_SOURCE[0]}:${FUNCNAME[0]}:${LINENO[0]}::x:: vXtrapCmd=("$vPtrapCmd" "$vPtrapCmd" '')
bash: FUNCNAME[0]: несвязанная переменная
++:${BASH_SOURCE[0]}:${FUNCNAME[0]}:${LINENO[0]}::x:: vXtrapArg0=("$vPtrapArg0" "$vPtrapArg0" '')
bash: FUNCNAME[0]: несвязанная переменная
++:${BASH_SOURCE[0]}:${FUNCNAME[0]}:${LINENO[0]}::x:: vXtrapArgC=("$vPtrapArgC" "$vPtrapArgC" '0')
bash: FUNCNAME[0]: несвязанная переменная
++:${BASH_SOURCE[0]}:${FUNCNAME[0]}:${LINENO[0]}::x:: vXtrapArgV=("$vPtrapArgV" "$vPtrapArgV" '')
bash: FUNCNAME[0]: несвязанная переменная
++:${BASH_SOURCE[0]}:${FUNCNAME[0]}:${LINENO[0]}::x:: vXtrapRc=('0' '0' '0')
bash: FUNCNAME[0]: несвязанная переменная
++:${BASH_SOURCE[0]}:${FUNCNAME[0]}:${LINENO[0]}::x:: vXtrapRcMsg=('' '' '')
bash: FUNCNAME[0]: несвязанная переменная
++:${BASH_SOURCE[0]}:${FUNCNAME[0]}:${LINENO[0]}::x:: set +o xtrace
100
110
ubuntu@ubuntu:/pool/src/trap/scr$

Я надеюсь, что этот код и вывод имеют смысл для тех, кто его читает.

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.