给定文件m.sh
:
f() {
echo foo
}
g() {
f | sed -r 's/^|$/:/g' # random work
}
和e.sh
:
. m.sh
old_f="$(type f | sed '3,$!d')"
f() {
echo "$(eval "$old_f")bar"
}
g
有没有比使用type
和eval
从重写函数调用旧函数更好的解决方案,同时保持相同的名称,以便其他函数中的引用仍然有效?
两者m.sh
都是e.sh
同一个项目的一部分,因此我们可以m.sh
放心修改。
答案1
我突然想到我可以这样做:
f_1() {
echo foo
}
f() { f_1 "$@"; }
g() {
f | sed -r 's/^|$/:/g' # random work
}
. m.sh
f_2() {
echo "$(f_1)bar"
}
f() { f_2 "$@"; }
g
不幸的是,这需要修改m.sh
以添加这样的样板,但至少它避免了使用type
和eval
。
通过使用第一个定义将其定义一次,可以避免手动重新定义f()
以增加数量:
f() {
"$(last_version_of_function "${FUNCNAME[0]}")" "$@"
}
通过使用这些定义:
reverse_identifier_words() {
awk -F_ '
BEGIN {
OFS="_"
}
{
for (i = 1; i <= NF / 2; i++) {
t = $i
$i = $(NF - i + 1)
$(NF - i + 1) = t
}
print
}
'
}
last_version_of_function() {
declare -F \
| grep -Eo "\b${1}_[0-9]+\$" \
| reverse_identifier_words \
| sort -rn -t_ -k1 \
| head -n1 \
| reverse_identifier_words
}
这样,e.sh
只需执行以下操作即可覆盖:
. m.sh
f_2() {
echo "$(f_1)bar"
}
g