zsh + ohmyzsh + powerlevel9k : 'sudo -s'를 발행 할 때 완료가 작동을 멈춤


1

MacOS High Sierra에서 zsh 및 ohmyzsh (powerlevel9k 테마 사용)에 이상한 문제가 있습니다.

sudo -s일부 스크립트의 성가신 이상한 출력을 얻을 때 ohmyzsh를 설치 한 후 . 그리고 모든 완성이 작동을 멈 춥니 다. Linux에서 동일한 구성이 예상대로 작동합니다.

그 모습은 다음과 같습니다.

user@host% sudo -s

bracketed-paste-magic () {
    # undefined
    builtin autoload -XUz
}
colors () {
    emulate -L zsh
    typeset -Ag color colour
    color=(00 none 01 bold 02 faint 22 normal 03 standout 23 no-standout 04 underline 24 no-underline 05 blink 25 no-blink 07 reverse 27 no-reverse 08 conceal 28 no-conceal 30 black 40 bg-black 31 red 41 bg-red 32 green 42 bg-green 33 yellow 43 bg-yellow 34 blue 44 bg-blue 35 magenta 45 bg-magenta 36 cyan 46 bg-cyan 37 white 47 bg-white 39 default 49 bg-default)
    local k
    for k in ${(k)color}
    do
        color[${color[$k]}]=$k
    done
    for k in ${color[(I)3?]}
    do
        color[fg-${color[$k]}]=$k
    done
    color[grey]=${color[black]}
    color[fg-grey]=${color[grey]}
    color[bg-grey]=${color[bg-black]}
    colour=(${(kv)color})
    local lc=$'\e[' rc=m
    typeset -Hg reset_color bold_color
    reset_color="$lc${color[none]}$rc"
    bold_color="$lc${color[bold]}$rc"
    typeset -AHg fg fg_bold fg_no_bold
    for k in ${(k)color[(I)fg-*]}
    do
        fg[${k#fg-}]="$lc${color[$k]}$rc"
        fg_bold[${k#fg-}]="$lc${color[bold]};${color[$k]}$rc"
        fg_no_bold[${k#fg-}]="$lc${color[normal]};${color[$k]}$rc"
    done
    typeset -AHg bg bg_bold bg_no_bold
    for k in ${(k)color[(I)bg-*]}
    do
        bg[${k#bg-}]="$lc${color[$k]}$rc"
        bg_bold[${k#bg-}]="$lc${color[bold]};${color[$k]}$rc"
        bg_no_bold[${k#bg-}]="$lc${color[normal]};${color[$k]}$rc"
    done
}
compdump () {
    # undefined
    builtin autoload -XUz
}
compinit () {
    emulate -L zsh
    setopt extendedglob
    typeset _i_dumpfile _i_files _i_line _i_done _i_dir _i_autodump=1
    typeset _i_tag _i_file _i_addfiles _i_fail=ask _i_check=yes _i_name
    while [[ $# -gt 0 && $1 = -[dDiuC] ]]
    do
        case "$1" in
            (-d) _i_autodump=1
                shift
                if [[ $# -gt 0 && "$1" != -[dfQC] ]]
                then
                    _i_dumpfile="$1"
                    shift
                fi ;;
            (-D) _i_autodump=0
                shift ;;
            (-i) _i_fail=ign
                shift ;;
            (-u) _i_fail=use
                shift ;;
            (-C) _i_check=
                shift ;;
        esac
    done
    typeset -gHA _comps _services _patcomps _postpatcomps
    typeset -gHA _compautos
    typeset -gHA _lastcomp
    if [[ -n $_i_dumpfile ]]
    then
        typeset -g _comp_dumpfile="$_i_dumpfile"
    else
        typeset -g _comp_dumpfile="${ZDOTDIR:-$HOME}/.zcompdump"
    fi
    typeset -gHa _comp_options
    _comp_options=(bareglobqual extendedglob glob multibyte multifuncdef nullglob rcexpandparam unset NO_allexport NO_aliases NO_cshnullglob NO_cshjunkiequotes NO_errexit NO_errreturn NO_globassign NO_globsubst NO_histsubstpattern NO_ignorebraces NO_ignoreclosebraces NO_kshglob NO_ksharrays NO_kshtypeset NO_markdirs NO_octalzeroes NO_posixbuiltins NO_posixidentifiers NO_shwordsplit NO_shglob NO_warnnestedvar NO_warncreateglobal)
    typeset -gH _comp_setup='local -A _comp_caller_options;
             _comp_caller_options=(${(kv)options[@]});
             setopt localoptions localtraps localpatterns ${_comp_options[@]};
             local IFS=$'\'\ \\t\\r\\n\\0\'';
             builtin enable -p \| \~ \( \? \* \[ \< \^ \# 2>&-;
             exec </dev/null;
             trap - ZERR;
             local -a reply;
             local REPLY;
             local REPORTTIME;
             unset REPORTTIME'
    typeset -ga compprefuncs comppostfuncs
    compprefuncs=()
    comppostfuncs=()
    : $funcstack
    compdef () {
        local opt autol type func delete eval new i ret=0 cmd svc
        local -a match mbegin mend
        emulate -L zsh
        setopt extendedglob
        if (( ! $# ))
        then
            print -u2 "$0: I need arguments"
            return 1
        fi
        while getopts "anpPkKde" opt
        do
            case "$opt" in
                (a) autol=yes  ;;
                (n) new=yes  ;;
                ([pPkK]) if [[ -n "$type" ]]
                    then
                        print -u2 "$0: type already set to $type"
                        return 1
                    fi
                    if [[ "$opt" = p ]]
                    then
                        type=pattern
                    elif [[ "$opt" = P ]]
                    then
                        type=postpattern
                    elif [[ "$opt" = K ]]
                    then
                        type=widgetkey
                    else
                        type=key
                    fi ;;
                (d) delete=yes  ;;
                (e) eval=yes  ;;
            esac
        done
        shift OPTIND-1
        if (( ! $# ))
        then
            print -u2 "$0: I need arguments"
            return 1
        fi
        if [[ -z "$delete" ]]
        then
            if [[ -z "$eval" ]] && [[ "$1" = *\=* ]]
            then
                while (( $# ))
                do
                    if [[ "$1" = *\=* ]]
                    then
                        cmd="${1%%\=*}"
                        svc="${1#*\=}"
                        func="$_comps[${_services[(r)$svc]:-$svc}]"
                        [[ -n ${_services[$svc]} ]] && svc=${_services[$svc]}
                        [[ -z "$func" ]] && func="${${_patcomps[(K)$svc][1]}:-${_postpatcomps[(K)$svc][1]}}"
                        if [[ -n "$func" ]]
                        then
                            _comps[$cmd]="$func"
                            _services[$cmd]="$svc"
                        else
                            print -u2 "$0: unknown command or service: $svc"
                            ret=1
                        fi
                    else
                        print -u2 "$0: invalid argument: $1"
                        ret=1
                    fi
                    shift
                done
                return ret
            fi
            func="$1"
            [[ -n "$autol" ]] && autoload -Uz "$func"
            shift
            case "$type" in
                (widgetkey) while [[ -n $1 ]]
                    do
                        if [[ $# -lt 3 ]]
                        then
                            print -u2 "$0: compdef -K requires <widget> <comp-widget> <key>"
                            return 1
                        fi
                        [[ $1 = _* ]] || 1="_$1"
                        [[ $2 = .* ]] || 2=".$2"
                        [[ $2 = .menu-select ]] && zmodload -i zsh/complist
                        zle -C "$1" "$2" "$func"
                        if [[ -n $new ]]
                        then
                            bindkey "$3" | IFS=$' \t' read -A opt
                            [[ $opt[-1] = undefined-key ]] && bindkey "$3" "$1"
                        else
                            bindkey "$3" "$1"
                        fi
                        shift 3
                    done ;;
                (key) if [[ $# -lt 2 ]]
                    then
                        print -u2 "$0: missing keys"
                        return 1
                    fi
                    if [[ $1 = .* ]]
                    then
                        [[ $1 = .menu-select ]] && zmodload -i zsh/complist
                        zle -C "$func" "$1" "$func"
                    else
                        [[ $1 = menu-select ]] && zmodload -i zsh/complist
                        zle -C "$func" ".$1" "$func"
                    fi
                    shift
                    for i
                    do
                        if [[ -n $new ]]
                        then
                            bindkey "$i" | IFS=$' \t' read -A opt
                            [[ $opt[-1] = undefined-key ]] || continue
                        fi
                        bindkey "$i" "$func"
                    done ;;
                (*) while (( $# ))
                    do
                        if [[ "$1" = -N ]]
                        then
                            type=normal
                        elif [[ "$1" = -p ]]
                        then
                            type=pattern
                        elif [[ "$1" = -P ]]
                        then
                            type=postpattern
                        else
                            case "$type" in
                                (pattern) if [[ $1 = (#b)(*)=(*) ]]
                                    then
                                        _patcomps[$match[1]]="=$match[2]=$func"
                                    else
                                        _patcomps[$1]="$func"
                                    fi ;;
                                (postpattern) if [[ $1 = (#b)(*)=(*) ]]
                                    then
                                        _postpatcomps[$match[1]]="=$match[2]=$func"
                                    else
                                        _postpatcomps[$1]="$func"
                                    fi ;;
                                (*) if [[ "$1" = *\=* ]]
                                    then
                                        cmd="${1%%\=*}"
                                        svc=yes
                                    else
                                        cmd="$1"
                                        svc=
                                    fi
                                    if [[ -z "$new" || -z "${_comps[$1]}" ]]
                                    then
                                        _comps[$cmd]="$func"
                                        [[ -n "$svc" ]] && _services[$cmd]="${1#*\=}"
                                    fi ;;
                            esac
                        fi
                        shift
                    done ;;
            esac
        else
            case "$type" in
                (pattern) unset "_patcomps[$^@]" ;;
                (postpattern) unset "_postpatcomps[$^@]" ;;
                (key) print -u2 "$0: cannot restore key bindings"
                    return 1 ;;
                (*) unset "_comps[$^@]" ;;
            esac
        fi
    }
    typeset _i_wdirs _i_wfiles
    _i_wdirs=()
    _i_wfiles=()
    autoload -Uz compaudit
    if [[ -n "$_i_check" ]]
    then
        typeset _i_q
        if ! eval compaudit
        then
            if [[ -n "$_i_q" ]]
            then
                if [[ "$_i_fail" = ask ]]
                then
                    if ! read -q "?zsh compinit: insecure $_i_q, run compaudit for list.
Ignore insecure $_i_q and continue [y] or abort compinit [n]? "
                    then
                        print -u2 "$0: initialization aborted"
                        unfunction compinit compdef
                        unset _comp_dumpfile _comp_secure compprefuncs comppostfuncs _comps _patcomps _postpatcomps _compautos _lastcomp
                        return 1
                    fi
                    _i_wfiles=()
                    _i_wdirs=()
                else
                    (( $#_i_wfiles )) && _i_files=("${(@)_i_files:#(${(j:|:)_i_wfiles%.zwc})}")
                    (( $#_i_wdirs )) && _i_files=("${(@)_i_files:#(${(j:|:)_i_wdirs%.zwc})/*}")
                fi
            fi
            typeset -g _comp_secure=yes
        fi
    fi
    autoload -Uz compdump compinstall
    _i_done=''
    if [[ -f "$_comp_dumpfile" ]]
    then
        if [[ -n "$_i_check" ]]
        then
            IFS=$' \t' read -rA _i_line < "$_comp_dumpfile"
            if [[ _i_autodump -eq 1 && $_i_line[2] -eq $#_i_files && $ZSH_VERSION = $_i_line[4] ]]
            then
                builtin . "$_comp_dumpfile"
                _i_done=yes
            fi
        else
            builtin . "$_comp_dumpfile"
            _i_done=yes
        fi
    fi
    if [[ -z "$_i_done" ]]
    then
        typeset -A _i_test
        for _i_dir in $fpath
        do
            [[ $_i_dir = . ]] && continue
            (( $_i_wdirs[(I)$_i_dir] )) && continue
            for _i_file in $_i_dir/^([^_]*|*~|*.zwc)(N)
            do
                _i_name="${_i_file:t}"
                (( $+_i_test[$_i_name] + $_i_wfiles[(I)$_i_file] )) && continue
                _i_test[$_i_name]=yes
                IFS=$' \t' read -rA _i_line < $_i_file
                _i_tag=$_i_line[1]
                shift _i_line
                case $_i_tag in
                    (\#compdef) if [[ $_i_line[1] = -[pPkK](n|) ]]
                        then
                            compdef ${_i_line[1]}na "${_i_name}" "${(@)_i_line[2,-1]}"
                        else
                            compdef -na "${_i_name}" "${_i_line[@]}"
                        fi ;;
                    (\#autoload) autoload -Uz "$_i_line[@]" ${_i_name}
                        [[ "$_i_line" != \ # ]] && _compautos[${_i_name}]="$_i_line"  ;;
                esac
            done
        done
        if [[ $_i_autodump = 1 ]]
        then
            compdump
        fi
    fi
    for _i_line in complete-word delete-char-or-list expand-or-complete expand-or-complete-prefix list-choices menu-complete menu-expand-or-complete reverse-menu-complete
    do
        zle -C $_i_line .$_i_line _main_complete
    done
    zle -la menu-select && zle -C menu-select .menu-select _main_complete
    bindkey '^i' | IFS=$' \t' read -A _i_line
    if [[ ${_i_line[2]} = expand-or-complete ]] && zstyle -a ':completion:' completer _i_line && (( ${_i_line[(i)_expand]} <= ${#_i_line} ))
    then
        bindkey '^i' complete-word
    fi
    unfunction compinit compaudit
    autoload -Uz compinit compaudit
    return 0
}
compinstall () {
    # undefined
    builtin autoload -XUz
}
down-line-or-beginning-search () {
    # undefined
    builtin autoload -XU
}
edit-command-line () {
    # undefined
    builtin autoload -XU
}
is-at-least () {
    emulate -L zsh
    local IFS=".-" min_cnt=0 ver_cnt=0 part min_ver version order
    min_ver=(${=1})
    version=(${=2:-$ZSH_VERSION} 0)
    while (( $min_cnt <= ${#min_ver} ))
    do
        while [[ "$part" != <-> ]]
        do
            (( ++ver_cnt > ${#version} )) && return 0
            if [[ ${version[ver_cnt]} = *[0-9][^0-9]* ]]
            then
                order=(${version[ver_cnt]} ${min_ver[ver_cnt]})
                if [[ ${version[ver_cnt]} = <->* ]]
                then
                    [[ $order != ${${(On)order}} ]] && return 1
                else
                    [[ $order != ${${(O)order}} ]] && return 1
                fi
                [[ $order[1] != $order[2] ]] && return 0
            fi
            part=${version[ver_cnt]##*[^0-9]}
        done
        while true
        do
            (( ++min_cnt > ${#min_ver} )) && return 0
            [[ ${min_ver[min_cnt]} = <-> ]] && break
        done
        (( part > min_ver[min_cnt] )) && return 0
        (( part < min_ver[min_cnt] )) && return 1
        part=''
    done
}
up-line-or-beginning-search () {
    # undefined
    builtin autoload -XU
}
url-quote-magic () {
    # undefined
    builtin autoload -XUz
}

root@host# echo $SHELL
zsh

root@host#

왜 그런 일이 일어날 수 있습니까? sudo -s모든 환경 변수 를 덮어 쓰지만 문제가 될 수 있다고 생각하지 않습니다.

환경 변수 :

root@host# echo $SHELL
zhs

root@host# dscl . -read $HOME UserShell
UserShell: /bin/zsh

일반 사용자와 동일합니다.


sudo -s사용자 root 로 새 쉘을 시작 합니다 . 이것은 또한 쉘이 루트 에서 구성을 가져갈 것임을 의미합니다 . "일부 스크립트의 성가신 이상한 출력"을 얻으면 루트 zsh 구성이 손상 되었다고 생각합니다 . bash현재 사용자의 로그인 쉘이 아닌 경우 일 수도 있습니다 zsh. echo $SHELL및 의 출력뿐만 아니라 해당 출력을 포함하도록 질문을 편집 할 수 dscl . -read $HOME UserShell있습니까?
Adaephon

출력 내용이 이미 질문에 있으므로주의 깊게 읽으십시오. 일반 사용자와 루트에 대해 다른 두 명령의 출력을 추가했습니다.
Drew

미안합니다. 초기 셸 프롬프트를 간과하고 구성이라고 가정했습니다.
Adaephon

답변:


0

주요 문제는 root 가 사용자와 다른 zsh 구성을 가지고 있다는 것 같습니다 . 같은 sudo -s대상 사용자 (의 구성을 사용하는 루트 ) 대신 호출 사용자, 당신은 다른 zsh을 구성을 얻을.

가에서 올 수 있었던 것처럼 출력은 보이는 functions(또는 내장 typeset -f또는 declare -f, 동등 함) 중 하나를 호출 할 것으로 보인다되는 루트의 구성 스크립트 :

/root/.zshrc
/root/.zshenv
/root/.zprofile
/root/.zlogin

모든 경우, 일반 사용자와 동일한 zsh 구성을 루트 에 제공 하는 것만으로 복사 할 수 있습니다.

  1. root로그인하십시오 . 예 :sudo -s
  2. 루트 가 가질 수 있는 zsh 구성 파일을 멀리 이동

    mkdir ~/zsh-old-conf
    mv ~/.zshrc ~/.zshenv ~/.zprofile ~/.zlogin ~/.oh-my-zsh ~/zsh-old-conf
  3. 일반 사용자 구성을 루트의 홈에 복사하십시오 .

    cp -r /Users/REGULAR/.zshrc /Users/REGULAR/.oh-my-zsh ~/
  4. 구성이 작동하는지 확인하십시오. 저장 측에 있으려면 현재 세션을 열어두고 다른 터미널에서 루트로 로그인하십시오. 이렇게하면 어떤 이유로 구성이 작동하지 않으면 변경 사항을 되돌릴 수 있습니다.


나는이 문제를 만들기 전에 그렇게 생각했습니다 ... 문제는 이것이 자동으로 가능한 설정입니다.. 구성은 루트 사용자와 루트가 아닌 사용자에 대해 완전히 동일합니다. 따라서이 솔루션이 도움이 될 가능성은 매우 낮았습니다. 지금 시도했지만 도움이되지 않았습니다.
Drew

할 때 사실, 변수를 여전히 그러므로 나는 심지어 모두 제거 할 수 있습니다, 루트가 아닌 사용자의 홈 디렉토리를 보여줍니다 과 에서 - 관련 파일을 참조 여전히 및 zsh을 + 완전히 새로운 쉘을 시작 할 때 ohmyzsh이 작업 이 ... 그러나 출력은 여전히 ​​지속됩니다.sudo -s$HOME.zsh*oh-my-zhs/var/root/sudo -s
Drew

그것은 ... 이상합니다. 나는 Mac에서이 테스트를하지 않았다는 것을 고백하지만, 그 것 sudo -s나를위한 리눅스보다는 Mac에서 다르게 작동 $HOME으로 재설정됩니다 /root. 당신은 시도 할 수 있습니까 sudo -i? -s초기 로그인 과 유사 하지만 초기 환경을 시뮬레이션하고 환경 변수를 사용자 기본값으로
재설정하고

더 자세히 말해 줄 수 있습니다.이 모든 작업을 수행 할 때 내 Mac의 루트 사용자가 비활성화되었습니다. macos 바보 기능이므로 시스템에 루트로 로그인 할 수 없지만 루트가 아닌 사용자 인 경우 관리자 권한을 사용하면 sudo -s일반 su이 작동하지 않고 간단한 Sorry문자열 을 반환 하지만 작업 을 수행 할 수 있습니다.
Drew

기술적으로 말하자면,이 경우 루트 사용자는 루트가 아닌 사용자의 zsh / oh-my-zsh 구성을 계속 사용합니다. 그래서 아마도 그 이유 때문일 것입니다 ... 그러나 "전통적인"sudo 사용자를 활성화 한 후에도 여전히 동일 ...
Drew
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.