![加载的运行帮助函数代码与磁盘中的实际源代码不匹配](https://linux22.com/image/219728/%E5%8A%A0%E8%BD%BD%E7%9A%84%E8%BF%90%E8%A1%8C%E5%B8%AE%E5%8A%A9%E5%87%BD%E6%95%B0%E4%BB%A3%E7%A0%81%E4%B8%8E%E7%A3%81%E7%9B%98%E4%B8%AD%E7%9A%84%E5%AE%9E%E9%99%85%E6%BA%90%E4%BB%A3%E7%A0%81%E4%B8%8D%E5%8C%B9%E9%85%8D.png)
从安装 zsh 开始,就打开了诸如,run-help
之类的命令的手册页(zsh 部分之一)。最近,我查找了函数源代码,发现大多数 zsh 命令/内置命令的帮助应该已经使用寻呼机打开。使用 打印加载函数的实际代码后,我注意到它与实际源代码不同。typeset
autoload
/usr/share/zsh/functions/Misc/run-help
functions run-help
这是两个版本以及它们之间的区别。请注意,第二个版本(源代码)也是由functions run-help
after I输出的有点解决了问题:
zsh加载的函数
run-help () {
emulate -RL zsh
local HELPDIR="${HELPDIR:-/usr/share/zsh/5.8/help}"
[[ $1 == "." ]] && 1="dot"
[[ $1 == ":" ]] && 1="colon"
if [[ $# == 0 || $1 == "-l" ]]
then
if [[ -d $HELPDIR ]]
then
echo "Here is a list of topics for which special help is available:"
echo ""
print -rc $HELPDIR/*(:t)
else
echo "There is no list of special help topics available at this time."
fi
return 0
elif [[ -n "${HELPDIR:-}" && -r $HELPDIR/$1 && $1 != compctl ]]
then
${=PAGER:-more} $HELPDIR/$1
return $?
fi
local what places noalias newline='
'
integer i=0 didman=0
places=("${(@f)$(builtin whence -va $1)}")
if [[ $places = *"not found"* && $1 != ${(Q)1} ]]
then
places=("${(@f)$(builtin whence -va ${(Q)1})}")
if (( ${#places} ))
then
set -- "${(Q)@}"
fi
noalias=1
fi
{
while ((i++ < $#places))
do
what=$places[$i]
[[ -n $noalias && $what = *" is an alias "* ]] && continue
builtin print -r $what
case $what in
(*( is an alias for (noglob|nocorrect))*) [[ ${what[(w)7]:t} != ${what[(w)1]} ]] && run_help_orig_cmd=${what[(w)1]} run-help ${what[(w)7]:t} ;;
(*( is an alias)*) [[ ${what[(w)6]:t} != ${what[(w)1]} ]] && run_help_orig_cmd=${what[(w)1]} run-help ${what[(w)6]:t} ;;
(*( is a * function)) case ${what[(w)1]} in
(comp*) man zshcompsys ;;
(zf*) man zshftpsys ;;
(run-help) man zshcontrib ;;
(*) builtin functions ${what[(w)1]} | ${=PAGER:-more} ;;
esac ;;
(*( is a * builtin)) case ${what[(w)1]} in
(compctl) man zshcompctl ;;
(comp*) man zshcompwid ;;
(bindkey|vared|zle) man zshzle ;;
(*setopt) man zshoptions ;;
(cap|getcap|setcap) ;&
(clone) ;&
(ln|mkdir|mv|rm|rmdir|sync) ;&
(sched) ;&
(echotc|echoti|sched|stat|zprof|zpty|zsocket|zstyle|ztcp) man zshmodules ;;
(zftp) man zshftpsys ;;
(*) man zshbuiltins ;;
esac ;;
(*( is hashed to *)) man ${what[(w)-1]:t} ;;
(*( is a reserved word)) man zshmisc ;;
(*) if ((! didman++))
then
if whence "run-help-$1:t" > /dev/null
then
local cmd_args
builtin getln cmd_args
builtin print -z "$cmd_args"
cmd_args=(${(z)cmd_args})
while [[ $cmd_args[1] != ${run_help_orig_cmd:-$1} ]]
do
shift cmd_args || return 1
done
eval "run-help-$1:t ${(q@)cmd_args[2,-1]}"
else
POSIXLY_CORRECT=1 man $@:t
fi
fi ;;
esac
if ((i < $#places && ! didman))
then
builtin print -nP "%SPress any key for more help or q to quit%s"
builtin read -k what
[[ $what != $newline ]] && echo
[[ $what == [qQ] ]] && break
fi
done
} always {
unset run_help_orig_cmd
}
}
源代码来自/usr/share/zsh/functions/Misc/run-help
run-help () {
emulate -RL zsh
local HELPDIR=${HELPDIR:-/usr/share/zsh/help}
[[ $1 == "." ]] && 1="dot"
[[ $1 == ":" ]] && 1="colon"
if [[ $# == 0 || $1 == "-l" ]]
then
if [[ -d $HELPDIR ]]
then
echo "Here is a list of topics for which special help is available:"
echo ""
print -rc $HELPDIR/*(:t)
else
echo "There is no list of special help topics available at this time."
fi
return 0
elif [[ -n "${HELPDIR:-}" && -r $HELPDIR/$1 && $1 != compctl ]]
then
${=PAGER:-/usr/bin/pager} $HELPDIR/$1
return $?
fi
local what places noalias newline='
'
integer i=0 didman=0
places=("${(@f)$(builtin whence -va $1)}")
if [[ $places = *"not found"* && $1 != ${(Q)1} ]]
then
places=("${(@f)$(builtin whence -va ${(Q)1})}")
if (( ${#places} ))
then
set -- "${(Q)@}"
fi
noalias=1
fi
{
while ((i++ < $#places))
do
what=$places[$i]
[[ -n $noalias && $what = *" is an alias "* ]] && continue
builtin print -r $what
case $what in
(*( is an alias for (noglob|nocorrect))*) [[ ${what[(w)7]:t} != ${what[(w)1]} ]] && run_help_orig_cmd=${what[(w)1]} run-help ${what[(w)7]:t} ;;
(*( is an alias)*) [[ ${what[(w)6]:t} != ${what[(w)1]} ]] && run_help_orig_cmd=${what[(w)1]} run-help ${what[(w)6]:t} ;;
(*( is a * function)) case ${what[(w)1]} in
(comp*) man zshcompsys ;;
(zf*) man zshftpsys ;;
(run-help) man zshcontrib ;;
(*) builtin functions ${what[(w)1]} | ${=PAGER:-/usr/bin/pager} ;;
esac ;;
(*( is a * builtin)) case ${what[(w)1]} in
(compctl) man zshcompctl ;;
(comp*) man zshcompwid ;;
(bindkey|vared|zle) man zshzle ;;
(*setopt) man zshoptions ;;
(cap|getcap|setcap) ;&
(clone) ;&
(ln|mkdir|mv|rm|rmdir|sync) ;&
(sched) ;&
(echotc|echoti|sched|stat|zprof|zpty|zsocket|zstyle|ztcp) man zshmodules ;;
(zftp) man zshftpsys ;;
(*) man zshbuiltins ;;
esac ;;
(*( is hashed to *)) man ${what[(w)-1]:t} ;;
(*( is a reserved word)) man zshmisc ;;
(*) if ((! didman++))
then
if whence "run-help-$1:t" > /dev/null
then
local cmd_args
builtin getln cmd_args
builtin print -z "$cmd_args"
cmd_args=(${(z)cmd_args})
while [[ $cmd_args[1] != ${run_help_orig_cmd:-$1} ]]
do
shift cmd_args || return 1
done
eval "run-help-$1:t ${(q@)cmd_args[2,-1]}"
else
POSIXLY_CORRECT=1 man $@:t
fi
fi ;;
esac
if ((i < $#places && ! didman))
then
builtin print -nP "%SPress any key for more help or q to quit%s"
builtin read -k what
[[ $what != $newline ]] && echo
[[ $what == [qQ] ]] && break
fi
done
} always {
unset run_help_orig_cmd
}
}
diff first second
3c3
< local HELPDIR="${HELPDIR:-/usr/share/zsh/5.8/help}"
---
> local HELPDIR=${HELPDIR:-/usr/share/zsh/help}
19c19
< ${=PAGER:-more} $HELPDIR/$1
---
> ${=PAGER:-/usr/bin/pager} $HELPDIR/$1
48c48
< (*) builtin functions ${what[(w)1]} | ${=PAGER:-more} ;;
---
> (*) builtin functions ${what[(w)1]} | ${=PAGER:-/usr/bin/pager} ;;
请注意第一个如何依赖于more
和/usr/share/zsh/5.8/help
。我的系统上也缺少该help
目录。/usr/share/zsh/5.8
我是如何“修复”它的
只是/usr/share/zsh/functions/Misc/run-help
通过在开头添加一条 echo 语句进行修改(在我删除它之后,无论如何我认为文件的修改确实解决了它)。之后,它每次都开始从磁盘加载正确的版本。
问题
你知道这是什么原因吗?我错过了什么吗?
答案1
当 zsh 加载函数代码时,它会加载包含已编译代码的文件(如果可用),否则读取源代码。编译后的代码位于 或/usr/share/zsh/functions/Misc/run-help.zwc
中/usr/share/zsh/functions/Misc.zwc
。请参阅自动加载功能手册更多细节。
如果run-help
比 更新run-help.zwc
,zsh 会忽略编译的文件。因此,修改/usr/share/zsh/functions/Misc
(以任何方式,甚至是假修改touch
)解决了你的问题。顺便说一句,如果编译的文件是目录范围的…/Misc.zwc
,这将无法解决您的问题。
看来您升级了 zsh。通常,如果安装过程创建编译文件,则升级过程应该更新这些编译文件。但由于某种原因,升级过程无法正常进行。
安装升级版本安装的文件,其修改时间是该文件在构建软件包的计算机上最后一次修改的日期。该日期可能早于创建文件的日期.zwc
,该日期可能是您在计算机上安装以前版本的 zsh 时的日期。
您可能想要完全卸载并重新安装 zsh,或者安排重新编译所有函数,因为这可能会影响run-help
.你需要运行zcompile
为此内置的。由于安装是在 下进行的/usr
,因此您需要以 root 身份进行安装。请注意,由于 zsh 安装在 下/usr
,因此您的发行版应该处理这个问题,并且手动执行此操作可能会破坏您的发行版所做的事情。