Mover-se de bash para zsh [closed]

141

Estou pensando em mudar do bash para o zsh, já que muitas vezes encontro postagens elogiando o zsh. Sou um usuário de linha de comando experiente e presumo que o básico seja praticamente o mesmo, por isso estou procurando conselhos para obter os benefícios de se movimentar e de que qualquer tipo de pegadinha esteja ciente.

Por favor, dê um pouco de conselho por resposta. Estou à procura de pedaços pequenos onde posso voltar e integrar informações extras no meu uso de shell em um ritmo constante, em vez de tentar aprender tudo de uma vez.

    
por Hamish Downer 07.08.2010 / 14:40

10 respostas

93

Como você disse, zsh é semelhante em muitos aspectos a bash . Ele tem alguns recursos que você não encontrará em bash e pode ser estendido de maneiras poderosas. Não pense em se mover como um tipo de revolução, mas sim como uma série de passos evolucionários que o ajudam em 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 percorrer os pontos um por um. Basta adicionar os bits interessantes ao seu ~/.zshrc e recarregar com source ~/.zshrc . Uma dica final: aprenda as combinações de teclas dos atalhos de teclado padrão do zsh ("Emacs"): ^A ^E ^W Alt-F Alt-B Alt-P ^L ^R . Você pode substituir Alt por dois toques de tecla separados: Alt-P é equivalente a ESC P .

Isso oferece uma conclusão de tabulação mais extensa.

autoload -U compinit
compinit

Conclusão de tabulação de ambas as extremidades.

setopt completeinword

O preenchimento de tabulação 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 ex. com ^ W.

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

Cores para ls.

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'

Um histórico para todos os shells abertos; armazene 10.000 entradas. Isso faz disso uma ajuda útil para encontrar os comandos que você usou da última vez para ./configure , etc. Use Alt-P (encontre o comando que começa assim) e ^ R (procure na história) livremente.

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

Habilita todos os tipos de globbing estendido, como ls ** / * .txt (localizar todos os arquivos de texto), ls -d *(D) (mostrar todos os arquivos incluindo aqueles que começam com "."). Para saber mais, acesse man zshexpn , seção "FILENAME GENERATION".

# superglobs
setopt extendedglob
unsetopt caseglob

Isso é útil para lembrar comandos em 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

Agradável prompt.

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 seu tamanho - útil ao decidir quais pacotes estão ocupando seu 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}'
}
    
por loevborg 08.08.2010 / 19:50
14

Eu recomendaria o livro Do bash ao Z Shell . Tem todos os conselhos que você precisa para mudar o seu shell. Ele explica as diferenças de ambos os shells e torna mais fácil para um novo zsher.

    
por qbi 07.08.2010 / 22:36
8

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

Meu arquivo .zshrc não contém nenhuma outra coisa realmente legal além de um timestamp no lado direito da linha de comando.

Btw, lembre-se de experimentar a complicação por abas em todos os lugares 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á achar útil abranger arquivos remotos completos:

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

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

Mas esteja avisado, esta concha o deixará preguiçoso e fará você sentir que uma concha padrão é estúpida e chata!

    
por LassePoulsen 07.08.2010 / 17:42
5

Um par de globs estendidos especificamente úteis:

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

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

3- chmod g+w **/*(U^I) - cria qualquer arquivo que pertença a mim e que não seja gravável em grupo, pode ser escrito em grupo

Sim, é claro que você pode escrever isso com find , mas isso é mais fácil de eliminar. Ele tem duas desvantagens, para ser justo, tanto para fazer com que todos sejam expandidos para a linha de comando: se ele corresponder a muitos 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á de setopt extendedglob se ainda não estiver)

    
por poolie 15.10.2010 / 03:21
4

Eu não sei muito sobre bash, então eu não posso 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 armazeno 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.]"
}
    
por Pedro 02.09.2010 / 21:54
3

Estou na mesma viagem:)

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

Considere este exemplo como link , veja os comentários e faça o seu caminho. Stackoverflow e severphault e bons lugares para pesquisar também.

Eu ainda tenho que mergulhar no link , mas não tenho muito tempo a perder:)

    
por tutuca 07.08.2010 / 16:41
3

Aprenda sobre o globbing estendido e globs recursivos em zsh.

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

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

Se você usa expressões regulares, procure em =~ (que o bash também tem) e considere: setopt rematch_pcre

Evite escrever scripts que dependam de mais do que um pouco da magia do zsh, porque embora seja fantástico de usar, o zsh pode tender a ser somente de escrita. Se você estiver usando muito mais, pense em quando mudar para um idioma como o Python.

Zsh é sedutor. É o lado negro. Bem-vindo.

    
por Phil P 02.09.2010 / 21:21
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          
    
por hariharan022 14.11.2010 / 09:39
1

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

link

    
por Rick 03.09.2010 / 03:56
0

Outro excelente recurso é a página de amantes do zsh (vem de site do grml zsh ).

    
por qbi 07.08.2010 / 22:38