加载的运行帮助函数代码与磁盘中的实际源代码不匹配

加载的运行帮助函数代码与磁盘中的实际源代码不匹配

从安装 zsh 开始,就打开了诸如,run-help之类的命令的手册页(zsh 部分之一)。最近,我查找了函数源代码,发现大多数 zsh 命令/内置命令的帮助应该已经使用寻呼机打开。使用 打印加载函数的实际代码后,我注意到它与实际源代码不同。typesetautoload/usr/share/zsh/functions/Misc/run-helpfunctions run-help

这是两个版本以及它们之间的区别。请注意,第二个版本(源代码)也是由functions run-helpafter 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,因此您的发行版应该处理这个问题,并且手动执行此操作可能会破坏您的发行版所做的事情。

相关内容