ฉันจะกำหนดฟังก์ชันทุบตีใหม่ในแง่ของคำนิยามเก่าได้อย่างไร


13

มีวิธีใดที่ฉันสามารถกำหนดฟังก์ชันทุบตีใหม่ในแง่ของนิยามเก่าหรือไม่? ยกตัวอย่างเช่นผมต้องการที่จะเพิ่มบล็อกของรหัสต่อไปคำนำของฟังก์ชั่นcommand_not_found_handle (),

# Check if $1 is instead a bash variable and print value if it is
local VAL=$(eval echo \"\$$1\")
if [ -n "$VAL" ] && [ $# -eq 1 ]; then
    echo "$1=$VAL"
    return $?
fi

ขณะนี้มีการกำหนดไว้ใน /etc/profile.d/PackageKit.sh และมีที่มาจากสคริปต์เริ่มต้นระบบ bash

ด้วยวิธีนี้ฉันสามารถค้นหาค่าของตัวแปรสภาพแวดล้อมที่พรอมต์คำสั่งเพียงพิมพ์ชื่อตัวแปร (และระบุว่าไม่มีคำสั่งดังกล่าวโดยใช้ชื่อนั้น) เช่น

user@hostname ~:$ LANG
LANG=en_AU.utf8

ฉันรู้ว่าฉันสามารถคัดลอกและวางคำจำกัดความปัจจุบันและเพิ่มการเปลี่ยนแปลงของตัวเองใน~/.bashrcแต่ฉันกำลังมองหาวิธีที่สวยงามมากขึ้นที่เกี่ยวข้องกับการใช้รหัสซ้ำ

วิธีที่ดีกว่าในการบรรลุเป้าหมายหรือการปรับปรุงรหัส / ส่วนขยายของฉันก็มีค่าเช่นกัน


หากคำถามนี้เหมาะกับ stackoverflow คนอื่นสามารถย้ายข้อมูลไปได้หรือไม่ฉันไม่รู้
tmoschou

3
ฉันคิดว่าโพสต์นี้ใน Stack Overflowตอบคำถามของคุณ
Mat

2
แทนที่จะevalใช้คุณสามารถใช้ทางอ้อม:local VAL=$(echo ${!1})
หยุดชั่วคราวจนกว่าจะมีประกาศเพิ่มเติม

คำตอบ:


14

คุณสามารถพิมพ์คำจำกัดความปัจจุบันของฟังก์ชั่นแล้วรวมไว้ในนิยามฟังก์ชันภายในส่วนevalคำสั่ง

current_definition=$(declare -f command_not_found_handle)
current_definition=${current_definition#*\{}
current_definition=${current_definition%\}}
prefix_to_add=$(cat <<'EOF'
  # insert code here (no special quoting required)
EOF
)
suffix_to_add=$(cat <<'EOF'
  # insert code here (no special quoting required)
EOF
)
eval "command_not_found_handle () {
  $prefix_to_add
  $current_definition
  $suffix_to_add
}"

อีกวิธีหนึ่งที่ฉันเห็นชัดเจนกว่าคือการกำหนดฟังก์ชั่นดั้งเดิมภายใต้ชื่อใหม่และเรียกสิ่งนั้นจากนิยามของคุณ ใช้งานได้เฉพาะในกรณีที่คุณไม่จำเป็นต้องดำเนินการกับตัวแปรท้องถิ่นของคำจำกัดความดั้งเดิม

eval "original_$(declare -f command_not_found_handle)"
command_not_found_handle () {
  
  original_command_not_found_handle
  
}

1
ไชโยไม่เคยเกิดขึ้นกับฉันที่จะใช้เอกสารที่นี่ไม่จำเป็นต้องมีข้อความพิเศษ ฉันคิดว่าฉันชอบวิธีแรกของคุณทำให้ง่ายต่อการดูคำจำกัดความทั้งหมดด้วยdeclare -fแต่ฉันชอบวิธีที่คุณเปลี่ยนชื่อ func ดั้งเดิม
tmoschou

0

ขอบคุณ @mat, @ dennis-williamson หลังจากอ่านความคิดเห็นของคุณนี่คือสิ่งที่ฉันได้รับ

eval 'command_not_found_handle () {

    local VAL=$(echo "${!1}")
    if [ -n "$VAL" ] && [ $# -eq 1 ]; then
            echo "$1=$VAL"
            return $?
    fi

    '$(declare -f command_not_found_handle |
    tail -n +3 | head -n -1)'
}'

แม้ว่าฉันคิดว่าฉันชอบโซลูชัน @Gilles

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.