Pasando de bash a zsh [cerrado]

143

Estoy considerando pasar de bash a zsh ya que a menudo me encuentro con publicaciones que elogian a zsh. Soy un usuario experimentado de la línea de comandos y supongo que los conceptos básicos son más o menos los mismos, por lo que estoy buscando consejos para obtener los beneficios de la mudanza, y cualquier problema que tenga en cuenta.

Por favor, solo da un consejo por respuesta. Estoy buscando fragmentos del tamaño de un bocado donde pueda volver e integrar bits adicionales de información en mi uso de shell a un ritmo constante en lugar de tratar de aprenderlo todo de una vez.

Hamish Downer
fuente
8
Me encantaría saber si es posible integrar el comando no encontrado de Ubuntu con zsh. Cambié de nuevo a bash por esto (y muchas otras molestias).
Marius Gedminas
Dos enlaces más interesantes: "Preguntas frecuentes sobre ZSH" zsh.sourceforge.net/FAQ y "ZSH es tu amigo" mikegrouchy.com/blog/zsh-is-your-friend.html
Shadok
3
@MariusGedminas: ( desde aquí ) zsh admite esto, pero debe habilitarlo manualmente. Solo agrégalo source /etc/zsh_command_not_founda tu .zshrc.
naught101

Respuestas:

94

Como dices, zshes similar en muchos aspectos a bash. Tiene algunas características que no encontrará bash, y se puede ampliar de manera poderosa. No pienses en moverte como una especie de revolución, sino como una serie de pasos evolutivos que te ayudan en tu trabajo diario. Aquí hay algunos consejos de mi .zshrc. Aunque diga que prefiere consejos únicos, esta publicación es una lista larga. Aún así, es una buena idea revisar los puntos uno por uno. Simplemente agregue los bits interesantes a su ~/.zshrcy vuelva a cargar con source ~/.zshrc. Un último consejo: aprender las pulsaciones de zsh'default s ( 'Emacs') atajos de teclado: ^A ^E ^W Alt-F Alt-B Alt-P ^L ^R. Puede reemplazar Altpor dos pulsaciones de teclas separadas: Alt-Pes equivalente a ESC P.


Esto le brinda una finalización de pestañas más extensa.

autoload -U compinit
compinit

Finalización de tabulación desde ambos extremos.

setopt completeinword

La finalización de la pestaña debe ser insensible a mayúsculas y minúsculas.

zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}'

Mejor terminación para killall.

zstyle ':completion:*:killall:*' command 'ps -u $USER -o cmd'

Cambia la definición de "palabra", por ejemplo, con ^ W.

autoload select-word-style
select-word-style shell

Colores para ls.

if [[ -x "`whence -p dircolors`" ]]; then
  eval `dircolors`
  alias ls='ls -F --color=auto'
else
  alias ls='ls -F'
fi

Atajos para ls.

alias ll='ls -l'
alias la='ls -a'

Una historia para todos los depósitos abiertos; almacenar 10,000 entradas. Esto lo convierte en una ayuda útil para la memoria para encontrar los comandos que usó la última vez, ./configureetc. Utilice Alt-P (comando de búsqueda que comienza así) y ^ R (búsqueda en el historial) generosamente.

HISTFILE=~/.zhistory
HISTSIZE=SAVEHIST=10000
setopt sharehistory
setopt extendedhistory

Habilita todo tipo de globbing extendido, como ls ** / *. Txt (buscar todos los archivos de texto), ls -d *(D)(mostrar todos los archivos, incluidos los que comienzan con "."). Para obtener más información, vaya a la man zshexpnsección "GENERACIÓN DE NOMBRES DE ARCHIVO".

# superglobs
setopt extendedglob
unsetopt caseglob

Esto es útil para recordar comandos en su historial sin ejecutarlos.

setopt interactivecomments # pound sign in interactive prompt

Escriba ".." en lugar de "cd ..", "/ usr / include" en lugar de "cd / usr / include".

setopt auto_cd

Buen aviso.

PS1='[%T] %n@%m:%~# '

Muestra las estadísticas de uso de la CPU para los comandos que toman más de 10 segundos

REPORTTIME=10

Algunos comandos que usa ampliamente en Ubuntu.

alias 'a=sudo aptitude'
alias 'ai=sudo aptitude install'
alias 'ar=sudo aptitude remove'
alias 'au=sudo aptitude update'
alias 'ag=sudo aptitude safe-upgrade'
alias 'as=apt-cache search'
alias 'aw=apt-cache show'

Enumera los paquetes ordenados por su tamaño, útil para decidir qué paquetes están ocupando su espacio en disco.

function apt-list-packages {
  dpkg-query -W --showformat='${Installed-Size} ${Package} ${Status}\n' | grep -v deinstall | sort -n | awk '{print $1" "$2}'
}
loevborg
fuente
66
+1 por ser útil. -1 para la defensa subrepticia de emacs!
Tríptico
2
También te puede gustar [ github.com/robbyrussell/oh-my-zshfont>(oh-my-zsh) que agrega muchos complementos a zsh.
RedPixel
14

Recomendaría el libro De bash a Z Shell . Tiene todos los consejos que necesita para cambiar su shell. Explica las diferencias de ambos shells y hace que sea fácil para un nuevo zsher.

qbi
fuente
El libro es ideal para usuarios de bash y zsh por igual. Tienes que amar cómo cada capítulo comienza con "tanto bash como zsh pueden hacer todo esto" y luego lleva a otras 30 páginas de "y aquí están las cosas únicas de zsh"
Rick
8

¡Aquí está mi .zshrc y eso es lo más importante! zsh tiene muchas opciones que puedes usar, así que mira algunos de los ejemplos en la red o lee la documentación en la página de inicio de Zsh .

Mi .zshrc no contiene cosas realmente geniales aparte de una marca de tiempo en el lado derecho de la línea de comando.

Por cierto, recuerde probar la compleción de tabulación en todos los ejemplos aquí:

mplayer -a[tab]

mostrará algo como esto:

mplayer -a
 -ac                 -- force usage of a specific audio codec
 -af                 -- activate audio filters
 -afm                -- force usage of a specific audio codec family
 -alang              -- select the DVD audio language
 -ao                 -- specify audio driver
 -aop                -- specify audio output filter

Y si usa ssh-keys sin contraseña o ssh-agent, puede resultarle útil tabular archivos remotos:

scp apollo:/home/user/[tab]
Desktop/ Documents/ Downloads/ Music/ Pictures/ Public/ Templates/ Videos/

Después de obtener la lista, puede presionar la pestaña más veces para recorrer las diferentes posibilidades.

Pero ten cuidado, ¡este caparazón te hará perezoso y te hará sentir que un caparazón estándar es estúpido y molesto!

LassePoulsen
fuente
5

Un par de globos extendidos específicamente útiles:

1- rmdir *(/^F)- eliminar todos los directorios no vacíos en el directorio actual

2- grep traceback /srv/log/**/*(.m-2)- busca esta expresión regular en archivos modificados en los últimos dos días

3- chmod g+w **/*(U^I)- hacer que los archivos que poseo y que no sean de escritura grupal sean de escritura grupal

Sí, por supuesto, puede escribir esto, findpero es más fácil de quitar. Para ser justos, tiene dos inconvenientes, ambos tienen que ver con que todos se expandan en la línea de comando: si coincide con muchos miles de archivos, la línea de comando será demasiado larga y esto fallará, y en segundo lugar se encuentran todos los archivos antes de que el archivo comience a ejecutarse.

(Necesitará setopt extendedglobsi eso no está activado)

billar
fuente
4

No sé mucho sobre bash, así que no puedo comparar. Algunos fragmentos de mi archivo de configuración zsh.

Alguna config

HISTFILE=~/.zsh_history
HISTSIZE=1000
SAVEHIST=1000
REPORTTIME=10 # print elapsed time when more than 10 seconds
setopt NO_HUP
setopt NO_LIST_BEEP
setopt LOCAL_OPTIONS # allow functions to have local options
setopt LOCAL_TRAPS # allow functions to have local traps
setopt HIST_VERIFY
setopt SHARE_HISTORY # share history between sessions ???
setopt EXTENDED_HISTORY # add timestamps to history
setopt PROMPT_SUBST
setopt CORRECT
setopt COMPLETE_IN_WORD
setopt IGNORE_EOF

setopt APPEND_HISTORY # adds history
setopt INC_APPEND_HISTORY SHARE_HISTORY  # adds history incrementally and share it across sessions
setopt HIST_IGNORE_ALL_DUPS  # don't record dupes in history
setopt HIST_REDUCE_BLANKS
# Leave some chars out of the out of WORDCHARS so ^W acts more nicely 
WORDCHARS='*?_-[]~\!#$%^(){}<>|`@#$%^*()+:?'

Git en el aviso

if [[ -n $SSH_CONNECTION ]]; then
  export PS1='%m:%3~$(git_info_for_prompt)%# '
else
  export PS1='%3~$(git_info_for_prompt)%# '
fi

Algunas teclas de acceso rápido, inserte un texto al principio de la línea.

insert_sudo     () { zle beginning-of-line; zle -U "sudo "         }
insert_apt      () { zle beginning-of-line; zle -U "sudo apt-get " }
insert_gem      () { zle beginning-of-line; zle -U "sudo gem "     }
insert_install  () { zle -U "install "     }

zle -N insert-sudo      insert_sudo
zle -N insert-apt       insert_apt
zle -N insert-gem       insert_gem
zle -N insert-install   insert_install

bindkey "^B" insert-gem
bindkey "^N" insert-install
bindkey "^k" insert-sudo
bindkey "^a" insert-apt

Las funciones, las guardo en ~ / .zsh / functions

El git_info_for_prompt

local g="$(git rev-parse --git-dir 2>/dev/null)"
if [ -n "$g" ]; then
  local r
  local b
  if [ -d "$g/../.dotest" ]
  then
    if test -f "$g/../.dotest/rebasing"
    then
      r="|REBASE"
    elif test -f "$g/../.dotest/applying"
    then
      r="|AM"
    else
      r="|AM/REBASE"
    fi
    b="$(git symbolic-ref HEAD 2>/dev/null)"
  elif [ -f "$g/.dotest-merge/interactive" ]
  then
    r="|REBASE-i"
    b="$(cat "$g/.dotest-merge/head-name")"
  elif [ -d "$g/.dotest-merge" ]
  then
    r="|REBASE-m"
    b="$(cat "$g/.dotest-merge/head-name")"
  elif [ -f "$g/MERGE_HEAD" ]
  then
    r="|MERGING"
    b="$(git symbolic-ref HEAD 2>/dev/null)"
  else
    if [ -f "$g/BISECT_LOG" ]
    then
      r="|BISECTING"
    fi
    if ! b="$(git symbolic-ref HEAD 2>/dev/null)"
    then
      if ! b="tag: $(git describe --exact-match HEAD 2>/dev/null)"
      then
        b="$(cut -c1-7 "$g/HEAD")..."
      fi
    fi
  fi

  if [ -n "$1" ]; then
    printf "$1" "${b##refs/heads/}$r"
  else
    printf "[%s]" "${b##refs/heads/}$r"
  fi
fi

Algunas opciones de github

#compdef github

_github() {
  if (( CURRENT > 2 )); then
    # shift words so _arguments doesn't have to be concerned with second command
    (( CURRENT-- ))
    shift words
    # use _call_function here in case it doesn't exist
    _call_function 1 _github_${words[1]}
  else
    _values "github command" \
     "fetch[Fetch from a remote to a local branch.]" \
     "ignore[Ignore a SHA (from 'github network commits')]" \
     "fetch_all[Fetch all refs from a user]" \
     "info[Info about this project.]" \
     "browse[Open this repo in a web browser.]" \
     "home[Open this repo's master branch in a web browser.]" \
     "clone[Clone a repo.]" \
     "pull-request[Generate the text for a pull request.]" \
     "network[Project network tools.]" \
     "pull[Pull from a remote.]" \
     "track[Track another user's repository.]"
  fi
}

_github_pull() {
  _arguments \
    "--merge[Automatically merge remote's changes into your master.]"
}
_github_clone() {
  _arguments \
    "--ssh[Clone using the [email protected] style url.]"
}

_github_track() {
  _arguments \
    "--private[Use [email protected]: instead of git://github.com/.]" \
    "--ssh[Equivalent to --private.]"
}

_github_network() {
  if (( CURRENT > 2 )); then
    # shift words so _arguments doesn't have to be concerned with second command
    (( CURRENT-- ))
    shift words
    # use _call_function here in case it doesn't exist
    _call_function 1 _github_network_${words[1]}
  else
    _values "github network command" \
     "web[Open network in a web browser.]" \
     "list[List networked repositories.]" \
     "fetch[Fetched commits for a given networked repository.]" \
     "commits[List networked commits not pulled into this repo.]"
  fi
}

_github_network_commits() {
  _arguments \
    "--project[Filter commits on a certain project.]" \
    "--author[Filter commits on a email address of author.]" \
    "--common[Show common branch point.]" \
    "--nocache[Do not use the cached network data.]" \
    "--sort[How to sort : date(*), branch, author.]" \
    "--thisbranch[Look at branches that match the current one]" \
    "--applies[Filter commits to patches that apply cleanly.]" \
    "--limit[Only look through the first X heads - useful for really large projects]" \
    "--before[Only show commits before a certain date.]" \
    "--after[Only show commits after a certain date.]" \
    "--shas[Only show shas.]" \
    "--cache[Use the network data even if it's expired.]" \
    "--noapply[Filter commits to patches that do not apply cleanly.]"
}

fuente
3

Estoy en el mismo viaje :)

Hasta ahora he descubierto que la cosa es tener un buen archivo de configuración (.zshrc).

Tome este como ejemplo http://matt.blissett.me.uk/linux/zsh/zshrc , mire los comentarios y háblelo. Stackoverflow y severphault y buenos lugares para buscar también.

Todavía tengo que sumergirme en http://dotfiles.org/.zshrc , pero no tengo tanto tiempo que perder :)

tutuca
fuente
3

Aprenda sobre el globbing extendido y los globos recursivos en zsh.

Aprenda un poco sobre zstyle y cómo varias cosas (especialmente la finalización) le permiten ajustar su configuración usando zstyle.

Mira en las matrices asociativas. También los arreglos estándar (¡cuidado con las diferencias de bash, para mejor!)

Si usa expresiones regulares, investigue =~(que bash también tiene) y considere:setopt rematch_pcre

Evite escribir guiones que dependan de más de un poco de la magia de zsh, porque si bien es fantástico de usar, zsh puede tender a ser de solo escritura. Si está usando mucho más, piense en cuándo cambiar a un lenguaje como Python.

Zsh es seductor. Es el lado oscuro. Bienvenidos.

Phil P
fuente
2

Gran beneficio: excelente finalización de pestañas con scripts de finalización preempaquetados para muchos comandos. Aquí hay un ejemplo que muestra la salida de apt-get<TAB>:

apt-get
action
autoclean        build-dep        clean            dselect-upgrade  install          remove           update           
autoremove       check            dist-upgrade     help             purge            source           upgrade          
hariharan022
fuente
1

He dado un par de charlas y he convertido a varias personas a zsh. Mantengo un repositorio de github de mis (cuáles son las ventajas) notas junto con un iniciador y una copia de mi propia configuración de zsh en github aquí.

http://github.com/mitechie/zshrc

Almiar
fuente