Переопределите функцию оболочки, сохраните ссылку на исходную

Можно ли переопределить функцию оболочки и сохранить ссылку на исходную?

f()  { echo original; }
f()  { echo wrapper; ...; }
f

Результат этого должен быть:

wrapper
original

Возможно ли это в полупортативном режиме?

Обоснование: я пытаюсь протестировать свою программу, заменив ее частью функциями оболочки, которые записывают свои вызовы в файл журнала. Это прекрасно работает, пока я только завершаю команды и встроенные команды, и пока я не возражаю против неизбирательного ведения журнала. Теперь я хотел бы сделать тестовый набор более удобным для обслуживания, только записывая интересную часть в каждом тесте.

Итак, пусть моя программа состоит из

f
g
h

где f, g, h - все функции оболочки, и я хотел бы отслеживать выполнение только g.

Ответ 1

Ответ Йенса правильный. Просто добавив ниже код для полноты.

Вы можете просто использовать его, как показано ниже:

eval "`declare -f f | sed '1s/.*/_&/'`" #backup old f to _f

f(){
    echo wrapper
    _f # pass "[email protected]" to it if required.
}

Я использовал такую ​​же логику здесь: fooobar.com/questions/540072/...

Ответ 2

Многие оболочки (zsh, ksh, bash по крайней мере) поддерживают typeset -f f, чтобы сбрасывать содержимое f(). Используйте это, чтобы сохранить текущее определение в файле; затем определите f() по своему усмотрению. Восстановите f() путем поиска файла, созданного с помощью typeset.

Если вы слегка измените сбрасываемую функцию (переименование f() до _f() в первой строке, немного сложнее, если f() рекурсивна или вызывает другие функции, которые вы frobbed одинаково), вы можете получить это для получения желаемого результата.