it-swarm.cn

从bash迁移到zsh

我正在考虑从bash转到zsh,因为我经常遇到赞美zsh的帖子。我是一名经验丰富的命令行用户,我假设基本知识几乎相同,所以我正在寻找建议,以获得移动的好处,以及任何需要注意的问题。

请给每个答案一点建议。我正在寻找一口大小的块,我可以回来并以稳定的速度将额外的信息集成到我的Shell使用中,而不是试图一次性学习它。

142
Hamish Downer

如你所说,zsh在许多方面与bash类似。它具有您在bash中找不到的一些功能,并且可以通过强大的方式进行扩展。不要把它看作是一种革命,而是作为一系列帮助你日常工作的进化步骤。以下是我的.zshrc的一些提示。虽然你说你更喜欢单一的建议,但这篇文章很长。仍然是一个接一个地完成这些要点的好主意。只需将有趣的位添加到~/.zshrc并使用source ~/.zshrc重新加载。最后一个提示:了解zsh的默认(“Emacs”)键盘快捷键的按键:^A ^E ^W Alt-F Alt-B Alt-P ^L ^R。您可以通过两个单独的键击来替换AltAlt-P相当于ESCP


这为您提供了更广泛的制表选项。

autoload -U compinit
compinit

从两端完成标签。

setopt completeinword

选项卡完成应不区分大小写。

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

更好地完成了killall。

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

更改“Word”的定义,例如与^ W。

autoload select-Word-style
select-Word-style Shell

Ls的颜色。

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

Ls的快捷方式。

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

所有开壳的历史;存储10,000个条目。这使得这成为一个有用的记忆辅助工具,可以找到上次用于./configure等的命令。使用Alt-P(找到这样开始的命令)和^ R(在历史中搜索)。

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

启用各种扩展的globbing,例如ls **/* .txt(查找所有文本文件),ls -d *(D)(显示所有文件,包括以“。”开头的文件)。要了解更多信息,请转到man zshexpn,“FILENAME GENERATION”部分。

# superglobs
setopt extendedglob
unsetopt caseglob

这对于记住历史记录中的命令而不执行它们非常有用。

setopt interactivecomments # pound sign in interactive Prompt

键入“..”而不是“cd ..”,“/ usr/include”而不是“cd/usr/include”。

setopt auto_cd

不错的提示。

PS1='[%T] %[email protected]%m:%~# '

显示超过10秒的命令的CPU使用率统计信息

REPORTTIME=10

您在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'

列出按大小排序的包 - 在确定哪些包占用磁盘空间时很有用。

function apt-list-packages {
  dpkg-query -W --showformat='${Installed-Size} ${Package} ${Status}\n' | grep -v deinstall | sort -n | awk '{print $1" "$2}'
}
94
loevborg

我会推荐这本书 从bash到Z Shell 。它具有切换Shell所需的所有建议。它解释了两种壳的不同之处,并使新的zsher变得容易。

14
qbi

这是我的 。zshrc ,这是最重要的事情! zsh有很多你可以使用的选项,所以看一下网上的一些例子或者阅读 Zsh主页 的文档。

除了命令行右侧的时间戳之外,我的.zshrc不包含任何非常酷的东西。

顺便说一句,记得在这里举几个例子的地方尝试tab-compleation:

mplayer -a[tab]

会显示这样的事情:

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

如果您使用无密码ssh-keys或ssh-agent,您可能会发现它对tabcomplete远程文件很有用:

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

获取列表后,您可以再次按Tab键以循环显示不同的可能性。

但要注意,这款外壳会让你变得懒惰,让你觉得标准外壳是愚蠢而烦人的!

8
LassePoulsen

一些特别有用的扩展球:

1- rmdir *(/^F) - 删除当前目录下的所有非空目录

2- grep traceback /srv/log/**/*(.m-2) - 在过去两天修改的文件中查找此正则表达式

3- chmod g+w **/*(U^I) - 使我拥有的任何文件而不是组可写的文件是可写组的

是的,当然你可以用find来写这个,但这更容易划掉。它确实有两个缺点,公平地说,它们都被扩展到命令行:如果它匹配数千个文件,命令行会变得太长而且会失败,其次找到所有文件在文件开始运行之前。

(如果尚未启用,则需要setopt extendedglob

5
poolie

我不太了解bash,所以我无法比较。我的zsh配置文件中的一些片段。

一些配置

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 in the Prompt

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

一些热键,在行的开头插入一些文字。

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

函数,我存储在〜/ .zsh/functions中

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

一些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.]"
}
4
Pedro

我在同一次旅行:)

到目前为止,我发现事情是要有一个好的配置文件(.zshrc)。

以这个为例 http://matt.blissett.me.uk/linux/zsh/zshrc ,查看评论并破解你的方式。 Stackoverflow和severphault以及搜索的好地方。

我还没有潜入 http://dotfiles.org/.zshrc ,但我没有那么多时间松开:)

3
tutuca

了解zsh中的扩展globbing和递归globs。

了解zstyle以及各种事物(特别是完成)如何让您使用zstyle调整其配置。

查看关联数组。也是标准阵列(要注意与bash的区别,为了更好!)

如果你使用正则表达式,请查看=~(bash也有)并考虑:setopt rematch_pcre

避免编写依赖于zsh魔法的脚本,因为虽然使用它很棒,但zsh可能倾向于只写。如果您使用的太多,请考虑何时切换到Python等语言。

Zsh是诱人的。这是黑暗的一面。欢迎。

3
Phil P

最大的好处 - 使用预打包的完成脚本完成许多命令的优秀选项卡完成。这是一个显示apt-get<TAB>输出的示例:

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

我给了一个谈话的轿跑车,并将几个人转为zsh。我在github中保留了我的(有什么好处)笔记的github repo以及我自己的zsh配置的启动器和副本。

http://github.com/mitechie/zshrc

1
Rick

另一个很好的资源是 zsh爱好者页面 (来自 grml zsh site )。

0
qbi