Как мне переопределить функцию bash в терминах старого определения?

13

Есть ли способ, которым я могу переопределить функцию bash в терминах ее старого определения? Например, я хотел бы добавить следующий блок кода в преамбулу функции 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, но я ищу более элегантный способ, который включает повторное использование кода.

Также приветствуются лучшие способы достижения моей цели или улучшения / расширения кода.

tmoschou
источник
Если этот вопрос лучше подходит для stackoverflow, может кто-нибудь перенести его, я не знаю как.
tmoschou
3
Я думаю, что этот пост на Stack Overflow отвечает на ваш вопрос.
Мат
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, но мне нравится, как вы переименовываете оригинальную функцию.
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.

tmoschou
источник