zsh + ohmyzsh + powerlevel9k: Fertigstellungen funktionieren nicht mehr, wenn 'sudo -s' ausgegeben wird

402
Drew

Ich habe ein seltsames Problem mit zsh und ohmyzsh (mit Powerlevel9k-Design) auf MacOS High Sierra.

Nach der Installation von ohmyzsh bei der Ausgabe sudo -sbekommen Sie nervige und seltsame Ausgaben eines Skripts. Und alle Abschlüsse hören auf zu arbeiten. Absolut dieselbe Konfiguration unter Linux funktioniert genau wie erwartet.

So sieht es aus:

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[$]=$k done for k in $ do color[fg-$]=$k done color[grey]=$ color[fg-grey]=$ color[bg-grey]=$ colour=(${(kv)color}) local lc=$'\e[' rc=m typeset -Hg reset_color bold_color reset_color="$lc$$rc" bold_color="$lc$$rc" typeset -AHg fg fg_bold fg_no_bold for k in ${(k)color[(I)fg-*]} do fg[$]="$lc$$rc" fg_bold[$]="$lc$;$$rc" fg_no_bold[$]="$lc$;$$rc" done typeset -AHg bg bg_bold bg_no_bold for k in ${(k)color[(I)bg-*]} do bg[$]="$lc$$rc" bg_bold[$]="$lc$;$$rc" bg_no_bold[$]="$lc$;$$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="$/.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 $; 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="$" svc="$" func="$_comps[$]" [[ -n $ ]] && svc=$ [[ -z "$func" ]] && func="${$:-$}" 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="$" svc=yes else cmd="$1" svc= fi if [[ -z "$new" || -z "$" ]] then _comps[$cmd]="$func" [[ -n "$svc" ]] && _services[$cmd]="$" 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_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 $na "$" "${(@)_i_line[2,-1]}" else compdef -na "$" "$" fi ;; (\#autoload) autoload -Uz "$_i_line[@]" $ [[ "$_i_line" != \ # ]] && _compautos[$]="$_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 [[ $ = expand-or-complete ]] && zstyle -a ':completion:' completer _i_line && (( $ <= ${#_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 [[ $ = *[0-9][^0-9]* ]] then order=($ $) if [[ $ = <->* ]] then [[ $order != ${${(On)order}} ]] && return 1 else [[ $order != ${${(O)order}} ]] && return 1 fi [[ $order[1] != $order[2] ]] && return 0 fi part=$ done while true do (( ++min_cnt > ${#min_ver} )) && return 0 [[ $ = <-> ]] && 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# 

Irgendwelche Ideen, warum es passieren könnte? Ich weiß, dass sudo -salle Umgebungsvariablen überschrieben werden, glaube aber nicht, dass dies ein Problem sein könnte.

Env vars:

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

Gleiches für normale Benutzer.

1
`sudo -s` startet eine neue Shell als Benutzer * root *. Dies bedeutet auch, dass die Shell ihre Konfiguration von * root * erhält. Wenn Sie "nervige und seltsame Ausgabe eines Skripts" erhalten, würde ich vermuten, dass * roots * `zsh`-Konfiguration defekt ist. Es könnte auch "bash" sein, wenn die Login-Shell Ihres aktuellen Benutzers nicht "zsh" ist. Bitte bearbeiten Sie Ihre Frage so, dass sie die fragliche Ausgabe sowie die Ausgaben von "echo $ SHELL" und "dscl" enthält. -read $ HOME UserShell`? Adaephon vor 6 Jahren 0
Der Inhalt der Ausgabe steht bereits in der Frage, bitte sorgfältig durchlesen. Ich habe die Ausgaben von zwei anderen Befehlen für normale Benutzer und root hinzugefügt Drew vor 6 Jahren 0
Das tut mir leid. Ich habe die ursprüngliche Shell-Eingabeaufforderung übersehen und davon ausgegangen, dass es Ihre Konfiguration ist. Adaephon vor 6 Jahren 0

1 Antwort auf die Frage

0
Adaephon

Das Hauptproblem scheint zu sein, dass root eine andere zsh-Konfiguration hat als Ihr Benutzer. wie sudo -sdie Konfiguration des Zielbenutzer (verwendet root ) anstelle des anrufenden Benutzers, erhalten Sie eine andere zsh Konfiguration.

Die Ausgabe sieht aus, als könnte sie vom functionseingebauten stammen (oder typeset -foder declare -f, was äquivalent ist), das in einem der Konfigurationsskripte von root aufgerufen wird :

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

Wenn Sie root nur die gleiche zsh-Konfiguration geben möchten, die Ihr normaler Benutzer hat, können Sie diese einfach kopieren:

  1. Melden Sie sich als root an, zsudo -s
  2. Entfernen Sie alle zsh-Konfigurationsdateien, die root möglicherweise hat

    mkdir ~/zsh-old-conf mv ~/.zshrc ~/.zshenv ~/.zprofile ~/.zlogin ~/.oh-my-zsh ~/zsh-old-conf 
  3. Kopieren Sie Ihre regulären Benutzerkonfiguration in das Stammverzeichnis von root :

    cp -r /Users/REGULAR/.zshrc /Users/REGULAR/.oh-my-zsh ~/ 
  4. Prüfen Sie, ob die Konfiguration jetzt funktioniert. Um auf der sicheren Seite zu sein, lassen Sie die aktuelle Sitzung geöffnet und melden Sie sich von einem anderen Terminal aus als root an. Auf diese Weise können Sie die Änderungen rückgängig machen, wenn die Konfiguration aus irgendeinem Grund nicht funktionieren sollte.

Ich dachte schon, bevor ich dieses Problem erstellt habe ... Das Problem ist, dass es sich um ein automatisiertes Setup handelt. Die Konfiguration ist für Root-Benutzer und Nicht-Root-Benutzer absolut identisch. Daher waren die Chancen, dass diese Lösung helfen konnte, sehr gering ... Ich habe es jetzt versucht und es hat nicht geholfen. Drew vor 6 Jahren 0
Wenn Sie `sudo -s` verwenden, zeigt die '$ HOME'-Variable immer noch das Heimatverzeichnis des Nicht-Root-Benutzers. Daher kann ich sogar alle mit .zsh * und` oh-my-zhs` zusammenhängenden Dateien entfernen `/ var / root /` und immer noch sehen, wie zsh + ohmyzsh funktioniert, wenn man eine komplett neue Shell startet und `sudo -s` dort macht ... Aber die Ausgabe bleibt bestehen .. Drew vor 6 Jahren 0
Das ist komisch. Ich gebe zu, dass ich das nicht auf einem Mac getestet habe, aber es scheint, dass sudo -s auf Macs anders funktioniert als unter Linux, da $ HOME auf `/ root` zurückgesetzt wird. Kannst du `sudo -i` versuchen? Es ähnelt `-s`, versucht jedoch, eine anfängliche Anmeldung zu simulieren, Umgebungsvariablen auf Benutzervorgaben zurückzusetzen, die Konfiguration zu lesen usw. Adaephon vor 6 Jahren 0
Ich kann Ihnen mehr sagen. Als ich das alles getan hatte, war der Root-Benutzer auf meinem Mac deaktiviert. Es ist eine dumme Funktion von Macos. Daher ist es nicht möglich, sich als Root am System anzumelden. Wenn Sie jedoch kein Root-Benutzer sind Mit Admin-Privilegien dürfen Sie `sudo -s` ausführen, obwohl einfaches` su` nicht funktioniert und eine einfache `Sorry`-Zeichenfolge zurückgibt Drew vor 6 Jahren 0
Technisch gesehen verwendet der Root-Benutzer in diesem Fall immer noch die zsh / oh-my-zsh-Konfiguration des Nicht-Root-Benutzers ... Also dachte ich, vielleicht liegt es daran ... Aber selbst wenn "traditioneller" Sudo-Benutzer aktiviert ist, ist es so immer noch die gleichen... Drew vor 6 Jahren 0
Seltsam, dass mit `sudo -i` mein` $ SHELL` `/ bin / sh` ist, obwohl ich es manuell in` root: *: 0: 0 geändert habe: Systemadministrator: / var / root: / usr / local / bin / zsh` in meinem `/ etc / passwd` Drew vor 6 Jahren 0
Es ist durchaus möglich, dass sich MacOS (nicht mehr?) Darum kümmert, was Sie in `/ etc / passwd` einstellen. Beachten Sie, dass die regulären Benutzer dort nicht einmal aufgeführt sind. Wenn ich die Manpage richtig verstehe (und wenn sie tatsächlich beschreibt, was wirklich passiert), könnte es sein, dass Sie eine `/ bin / sh'-Sitzung anstelle von` zsh` erhalten, wenn Sie `sudo -s` oder` sudo -i` ausführen . Sie könnten `sudo -i zsh -l` versuchen. Die einzige andere Sache, die ich mir vorstellen kann, ist, * keine * Shell-Sitzungen als root und intead auszuführen. Führen Sie einfach 'sudo COMMAND' aus, wenn Sie erhöhte Berechtigungen benötigen. Mir scheint, dass Apple wirklich nicht will, dass sich Benutzer als root anmelden. Adaephon vor 6 Jahren 0
das ist interessant, aber wenn ich `sudo -i zsh -l` gemacht habe, funktionierte es wie erwartet ... warum ???? Drew vor 6 Jahren 0
Ohne Befehl entscheidet `sudo -i` selbst, welche Shell gestartet werden soll. Und unter MacOS scheint dies `/ bin / sh` zu sein. Durch explizites Übergeben von "zsh -l" als Argument zwingen Sie "sudo", "zsh" auszuführen. `-l` weist` zsh` an, als * Login-Shell * auszuführen, liest also alle oben genannten Konfigurationsdateien. Es kann auch möglich sein, es wegzulassen oder durch "-i" (für * Interactive Shell *) zu ersetzen. Dann würde es nur aus ".zshrc" und ".zshenv" gelesen. Adaephon vor 6 Jahren 0
Ok, wenn ich `sudo -i` mache - bekomme ich tatsächlich / bin / sh. Wenn "sudo -i zsh" - dann bekomme ich / usr / local / bin / zsh mit dieser seltsamen Ausgabe, die in OP ist. Und nur wenn ich sudo sage, dass es zsh als * login shell * verwenden soll: `sudo -i zsh -l`, bekomme ich das normal erwartete Verhalten. Haben Sie Ideen, wie Sie das erklären können? Drew vor 6 Jahren 0
Oh, Moment mal!!! Ich habe es noch ein paar Mal ausprobiert und jetzt bekomme ich diese Ausgabe sogar mit "sudo -i zsh -l" ... Das ist einfach verrückt! Ich bin so verwirrt. Drew vor 6 Jahren 0
Finden Sie andere Personen mit dem gleichen Problem und ohne Lösung: https://stackoverflow.com/questions/41182414/oh-my-zsh-completion-not-working Drew vor 6 Jahren 0