Movendo do bash para o zsh [fechado]

143

Estou pensando em mudar do bash para o zsh, pois geralmente encontro posts elogiando o zsh. Eu sou um usuário experiente da linha de comando e estou assumindo que o básico é praticamente o mesmo, portanto, estou procurando conselhos para obter os benefícios da mudança e quaisquer dicas a serem observadas.

Por favor, dê um conselho por resposta. Estou procurando por pedaços pequenos, em que possa voltar e integrar informações extras ao uso do meu shell a um ritmo constante, em vez de tentar aprender tudo de uma só vez.

Hamish Downer
fonte
8
Gostaria de saber se é possível integrar o comando não encontrado do Ubuntu com o zsh. Voltei ao bash por causa disso (e muitos outros aborrecimentos).
Marius Gedminas 30/09/10
Dois links mais interessantes: "ZSH FAQ" zsh.sourceforge.net/FAQ & "ZSH é seu amigo" mikegrouchy.com/blog/zsh-is-your-friend.html
Shadok
3
@MariusGedminas: (a partir daqui ) O zsh suporta isso, mas você deve habilitá-lo manualmente. Basta adicionar source /etc/zsh_command_not_foundao seu .zshrc.
precisa saber é o seguinte

Respostas:

94

Como você diz, zshé semelhante em muitos aspectos bash. Ele possui alguns recursos que você não encontrará bashe pode ser estendido de maneiras poderosas. Não pense em se mover como um tipo de revolução, mas como uma série de etapas evolutivas que o ajudam no seu trabalho diário. Aqui estão algumas dicas do meu .zshrc. Embora você diga que prefere conselhos únicos, este post é uma lista longa. Ainda assim, é uma boa ideia analisar os pontos um a um. Basta adicionar os bits interessantes ao seu ~/.zshrce recarregar source ~/.zshrc. Uma dica final: aprender as teclas de zsh's atalhos de teclado padrão ( 'Emacs'): ^A ^E ^W Alt-F Alt-B Alt-P ^L ^R. Você pode substituir Altpor duas teclas separadas: Alt-Pé equivalente a ESC P.


Isso fornece uma conclusão mais abrangente da guia.

autoload -U compinit
compinit

Conclusão da guia pelas duas extremidades.

setopt completeinword

A conclusão da guia não diferencia maiúsculas de minúsculas.

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

Melhor conclusão para killall.

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

Altera a definição de "palavra", por exemplo, com ^ W.

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

Cores para sl.

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

Atalhos para ls.

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

Uma história para todas as conchas abertas; armazene 10.000 entradas. Isso torna isso um útil auxílio à memória para encontrar os comandos que você usou da última vez, ./configureetc. Use Alt-P (comando find que começa assim) e ^ R (pesquisa no histórico) liberalmente.

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

Permite todos os tipos de globos estendidos, como ls ** / *. Txt (encontre todos os arquivos de texto), ls -d *(D)(mostre todos os arquivos, incluindo os que começam com "."). Para saber mais, vá para a man zshexpnseção "GERAÇÃO DE NOME DO ARQUIVO".

# superglobs
setopt extendedglob
unsetopt caseglob

Isso é útil para lembrar comandos no seu histórico sem executá-los.

setopt interactivecomments # pound sign in interactive prompt

Digite ".." em vez de "cd ..", "/ usr / include" em vez de "cd / usr / include".

setopt auto_cd

Prompt agradável.

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

Exibir estatísticas de uso da CPU para comandos que levam mais de 10 segundos

REPORTTIME=10

Alguns comandos que você usa extensivamente no 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'

Lista os pacotes classificados por tamanho - útil para decidir quais pacotes estão ocupando espaço em disco.

function apt-list-packages {
  dpkg-query -W --showformat='${Installed-Size} ${Package} ${Status}\n' | grep -v deinstall | sort -n | awk '{print $1" "$2}'
}
Loevborg
fonte
6
+1 por ser útil. -1 para advocacia clandestina do emacs!
Triptych
2
Você também pode gostar do [ github.com/robbyrussell/oh-my-zshunette ( oh-my-zsh)), que adiciona muitos plugins ao zsh.
RedPixel
14

Eu recomendaria o livro From bash to Z Shell . Ele tem todos os conselhos que você precisa para mudar seu shell. Explica as diferenças de ambas as conchas e facilita para um novo zsher.

qbi
fonte
O livro é ótimo para usuários do bash e do zsh. Você precisa amar como cada capítulo começa com "o bash e o zsh podem fazer tudo isso" e, em seguida, leva a outras 30 páginas de "e aqui estão as coisas do zsh only"
Rick
8

Aqui está o meu .zshrc e essa é a coisa mais importante! O zsh tem muitas opções que você pode usar, então veja alguns de todos os exemplos da rede ou leia a documentação na página inicial do Zsh .

Meu .zshrc não contém nada realmente interessante além de um carimbo de data / hora no lado direito da linha de comando.

Btw, lembre-se de tentar a complementação de guias em todos os lugares onde alguns exemplos aqui:

mplayer -a[tab]

mostrará algo assim:

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

E se você usar ssh-keys sem senha ou ssh-agent, poderá ser útil para tabcompletar arquivos remotos:

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

Depois de obter a lista, você pode pressionar tab mais vezes para percorrer as diferentes possibilidades.

Mas esteja avisado, este shell fará com que você seja preguiçoso e faça com que você sinta que um shell padrão é estúpido e irritante!

LassePoulsen
fonte
5

Alguns globs estendidos especificamente úteis:

1- rmdir *(/^F)- exclua todos os diretórios não vazios do diretório atual

2- grep traceback /srv/log/**/*(.m-2)- procure esse regex em arquivos modificados nos últimos dois dias

3- chmod g+w **/*(U^I)- torne todos os arquivos de minha propriedade e não graváveis ​​em grupo graváveis ​​em grupo

Sim, é claro que você pode escrever isso, findmas isso é mais fácil. Ele tem duas desvantagens, para ser justo, ambas relacionadas à expansão da linha de comando: se ela corresponder a milhares de arquivos, a linha de comando ficará muito longa e isso falhará, e, em segundo lugar, todos os arquivos serão encontrados. antes que o arquivo comece a ser executado.

(Você precisará setopt extendedglobse isso ainda não estiver ativado)

poolie
fonte
4

Eu não sei muito sobre bash, então não consigo compilar. Alguns trechos do meu arquivo de configuração zsh.

Alguma configuração

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 no prompt

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

Algumas teclas de atalho, insira no início da linha algum texto.

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

As funções, eu guardo em ~ / .zsh / functions

O 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

Algumas opções do 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.]"
}

fonte
3

Estou na mesma viagem :)

Até agora, descobri que a coisa é ter um bom arquivo de configuração (.zshrc).

Tome este como exemplo http://matt.blissett.me.uk/linux/zsh/zshrc , veja os comentários e faça o seu caminho. Stackoverflow e severphault e bons locais para pesquisar também.

Ainda não mergulhei em http://dotfiles.org/.zshrc , mas não tenho muito tempo a perder :)

tutuca
fonte
3

Aprenda sobre os globs estendidos e recursivos estendidos no zsh.

Aprenda um pouco sobre o zstyle e como várias coisas (especialmente a conclusão) permitem ajustar sua configuração usando o zstyle.

Olhe para as matrizes associativas. Também as matrizes padrão (cuidado com as diferenças do bash, para melhor!)

Se você usar expressões regulares, consulte =~(que o bash também possui) e considere:setopt rematch_pcre

Evite escrever scripts que dependam de mais do que um pouco da mágica do zsh, porque, embora seja fantástico usá-lo, o zsh pode tender a ser apenas de gravação. Se você estiver usando muito mais, pense em quando mudar para uma linguagem como Python.

Zsh é sedutor. É o lado sombrio. Bem vinda.

Phil P
fonte
2

Grande benefício - excelente conclusão de guias com scripts de conclusão pré-empacotados para muitos comandos. Aqui está um exemplo mostrando a saída 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
fonte
1

Eu dei um cupê de palestras e converti várias pessoas para o zsh. Eu mantenho um repositório no github das minhas (quais são as vantagens), juntamente com um iniciador e uma cópia da minha própria configuração do zsh no github aqui.

http://github.com/mitechie/zshrc

Rick
fonte