Score:0

การรันโค้ดเดียวกันกับ -u และ +u ให้ผลลัพธ์ที่แตกต่างกัน

ธง cn

ฉันมีชุดสคริปต์ที่ค่อนข้างใหญ่ซึ่งเป็นส่วนเริ่มต้นของการสร้างตรรกะการดีบัก/การบันทึกสำหรับสคริปต์ทุบตี มีรหัสจำนวนมากในระบบ โชคดีที่ฉันสามารถแสดงผลลัพธ์ต่างๆ ที่ฉันไม่สามารถอธิบายได้เมื่อเรียกใช้สคริปต์ +u และ -u ตั้งค่าตัวแปรตามที่ทดสอบโดยใช้ +u กลายเป็นตัวแปรที่ไม่ได้ตั้งค่าเมื่อรันด้วย -u ชื่อ varibl.e ในกรณีนี้คือ $FUNCNAME

สคริปต์การทดสอบสั้น ๆ มีดังนี้:

#!/bin/bash


### ชุด -e
### ตั้ง -f
### ชุด -u
### ชุด -C
### ชุด -P
### ตั้งค่า -o ไปป์ไลน์


ส่งออก 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=()

    #เปลี่ยนLINENO 
    # โดยที่ BASH_LINENO[lIdx] ควรเท่ากับ vXtrapLNo[lIdx+1]
ส่งออก vXtrapLNo=()

    #การเริ่มต้นLINENO
    # บรรทัดรายงานเริ่มต้นของฟังก์ชันใน Debug Trap
ส่งออก vXtrapLNI=()

    # แทนที่ BASH_COMMAND
    # นี่คือคำสั่งซอร์สต้นฉบับที่ไม่ถูกแทนที่
    # ต่อไปนี้คือคำสั่งซอร์สเวอร์ชันบีบอัดที่ถูกแทนที่
    # "${vXtrcTrapArg0[$lIdx]} ${vXtrcTrapArgV[$lIdx]}"
ส่งออก vXtrapCmd=()

    # แทนที่ BASH_ARGV0
ส่งออก vXtrapArg0=()

    # การแทนที่ BASH_ARGVC
ส่งออก vXtrapArgC=()

# การแทนที่ BASH_ARGV
#คั่นด้วยช่องว่าง
ส่งออก vXtrapArgV=()

    # เปลี่ยน $?
ส่งออก vXtrapRc=()

    # ข้อความแทนที่ syserr
ส่งออก vXtrapRcMsg=()

ตั้ง +o อย่างละเอียด

อ่าน -rp '090'

#####
# ถ่ายโอนการเริ่มต้นคำสั่งเริ่มต้นไปยังตารางการติดตามที่แก้ไข
#####

ฉัน=0
iMax=${#BASH_LINENO[@]}
เจ=0
k=0
วี=''

พิมพ์f '\n'
v="$BASH_SUBSHELL"
ถ้า [[ -z "$v" && -n "${v-_}" ]]; แล้ว
    echo '$BASH_SUBSHELL unset' "$BASH_SUBSHELL"
อื่น
    เสียงสะท้อน '$BASH_SUBSHELL ชุด ' "$BASH_SUBSHELL"
ไฟ

v="$LINENO"
ถ้า [[ -z "$v" && -n "${v-_}" ]]; แล้ว
    echo '$LINENO unset' "$LINENO"
อื่น
    echo '$LINENO ชุด '"$LINENO"
ไฟ

v="$BASH_COMMAND"
ถ้า [[ -z "$v" && -n "${v-_}" ]]; แล้ว
    echo '$BASH_COMMAND unset' "$BASH_COMMAND"
อื่น
    echo '$BASH_COMMAND ตั้ง' "$BASH_COMMAND"
ไฟ

สำหรับ (( i=0; i<=iMax; i++ ))
ทำ
    พิมพ์f '\n'

    v="${BASH_SOURCE["$i"]}"
    ถ้า [[ -z "$v" && -n "${v-_}" ]]; แล้ว
        echo '${BASH_SOURCE['"$i"']} unset '"${BASH_SOURCE[$i]}"
    อื่น
        echo '${BASH_SOURCE['"$i"']} set '"${BASH_SOURCE[$i]}"
    ไฟ

    v="${FUNCNAME[$i]}"
    ถ้า [[ -z "$v" && -n "${v-_}" ]]; แล้ว
        echo '${FUNCNAME['"$i"']} unset '"${FUNCNAME[$i]}"
    อื่น
        echo '${FUNCNAME['"$i"']} set '"${FUNCNAME[$i]}"
    ไฟ

    v="${BASH_LINENO["$i"]}"
    ถ้า [[ -z "$v" && -n "${v-_}" ]]; แล้ว
        echo '${BASH_LINENO['"$i"']} unset '"${BASH_LINENO[$i]}"
    อื่น
        echo '${BASH_LINENO['"$i"']} set '"${BASH_LINENO[$i]}"
    ไฟ

    v="${BASH_ARGV0[i]}"
    ถ้า [[ -z "$v" && -n "${v-_}" ]]; แล้ว
        echo '${BASH_ARGV0['"$i"']} unset '"${BASH_ARGV0[$i]}"
    อื่น
        echo '${BASH_ARGV0['"$i"']} set '"${BASH_ARGV0[$i]}"
    ไฟ

    v="${BASH_ARGC[i]}"
    ถ้า [[ -z "$v" && -n "${v-_}" ]]; แล้ว
        echo '${BASH_ARGC['"$i"']} unset '"${BASH_ARGC[$i]}"
    อื่น
        echo '${BASH_ARGC['"$i"']} set '"${BASH_ARGC[$i]}"
    ไฟ

    เจ=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"]}"
        ไฟ
        (( k++ ))
        (( j++ ))
    เสร็จแล้ว
เสร็จแล้ว

vPtrapScr="$(ชื่อฐาน "${BASH_SOURCE[0]}" '.sh' )"

vPtrapArgC='1'
vPtrapArgV=''
ในขณะที่ [ $vPtrapArgC -lt ${BASH_ARGC[0]} ]
ทำ
    กรณี "$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 Trap สิ่งเหล่านี้จะเป็นคำสั่งสคริปต์ปัจจุบัน
vXtrapCmd=( "$vPtrapCmd" "$vPtrapCmd" '' )
vXtrapArg0=( "$vPtrapArg0" "$vPtrapArg0" '' )
vXtrapArgC=( "$vPtrapArgC" "$vPtrapArgC" '0' )
vXtrapArgV=( "$vPtrapArgV" "$vPtrapArgV" '' )
vXtrapRc=( '0' '0' '0' )
vXtrapRcMsg=( '' '' '' )

ตั้ง +o xtrace

อ่าน -rp '100'

ยกเลิกการตั้งค่า
ยกเลิกการตั้งค่า iMax
ยกเลิกการตั้งค่า J
ยกเลิกการตั้งค่า k
ยกเลิกการตั้งค่า v
ยกเลิกการตั้งค่า vPtrapScr
ยกเลิกการตั้งค่า vPtrapCmd
ยกเลิกการตั้งค่า vPtrapArg0
ยกเลิกการตั้งค่า vPtrapArgC
ยกเลิกการตั้งค่า vPtrapArgV

อ่าน -rp '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=()

        #เปลี่ยนLINENO 
        # โดยที่ BASH_LINENO[lIdx] ควรเท่ากับ vXtrapLNo[lIdx+1]
ส่งออก vXtrapLNo=()

        #การเริ่มต้นLINENO
        # บรรทัดรายงานเริ่มต้นของฟังก์ชันใน Debug Trap
ส่งออก 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 set echo '$BASH_COMMAND set ' "$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]} ตั้งค่า ref=${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:: ตั้งค่า +o xtrace
100
110
ubuntu@ubuntu:/pool/src/trap/scr$ set -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=()

        #เปลี่ยนLINENO 
        # โดยที่ BASH_LINENO[lIdx] ควรเท่ากับ vXtrapLNo[lIdx+1]
ส่งออก vXtrapLNo=()

        #การเริ่มต้นLINENO
        # บรรทัดรายงานเริ่มต้นของฟังก์ชันใน Debug Trap
ส่งออก 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 set echo '$BASH_COMMAND set ' "$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$

ฉันหวังว่ารหัสและผลลัพธ์นี้จะสมเหตุสมผลสำหรับผู้ที่อ่าน

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา