ย้ายจาก bash เป็น zsh [ปิด]


143

ฉันกำลังพิจารณาที่จะย้ายจากทุบตีไปยัง zsh เพราะฉันมักเจอข้อความยกย่อง zsh ฉันเป็นผู้ใช้บรรทัดคำสั่งที่มีประสบการณ์และฉันคิดว่าพื้นฐานนั้นเหมือนกันมากดังนั้นฉันจึงมองหาคำแนะนำเพื่อให้ได้ประโยชน์จากการเคลื่อนไหวและ gotchas ใด ๆ ที่ต้องระวัง

โปรดให้คำแนะนำหนึ่งข้อต่อหนึ่งคำตอบ ฉันกำลังมองหาชิ้นที่มีขนาดพอดีคำซึ่งฉันสามารถกลับมาและรวมข้อมูลพิเศษเข้ากับการใช้งานเชลล์ของฉันได้อย่างมั่นคงแทนที่จะพยายามเรียนรู้ทุกอย่างในครั้งเดียว


8
ฉันชอบที่จะรู้ว่าเป็นไปได้ที่จะรวมคำสั่งของ Ubuntu ที่ไม่พบกับ zsh ฉันเปลี่ยนกลับไปทุบตีเพราะสิ่งนี้ (และความรำคาญอื่น ๆ อีกมากมาย)
Marius Gedminas


ลิงก์ที่น่าสนใจอีกสองรายการ: "ZSH FAQ" zsh.sourceforge.net/FAQ & "ZSH เป็นเพื่อนของคุณ" mikegrouchy.com/blog/zsh-is-your-friend.html
Shadok

3
@MariusGedminas: ( จากที่นี่ ) zsh สนับสนุนสิ่งนี้ แต่คุณต้องเปิดใช้งานด้วยตนเอง เพียงแค่เพิ่มที่คุณsource /etc/zsh_command_not_found .zshrc
naught101

คำตอบ:


94

ในขณะที่คุณพูดว่าจะคล้ายกันในหลายประการที่จะzsh bashมันมีคุณสมบัติบางอย่างที่คุณจะไม่พบbashและมันสามารถขยายออกไปได้ด้วยวิธีที่ทรงพลัง อย่าคิดว่าการเคลื่อนไหวเป็นการปฏิวัติ แต่เป็นขั้นตอนวิวัฒนาการหลายอย่างที่จะช่วยคุณในการทำงานประจำวัน .zshrcต่อไปนี้เป็นคำแนะนำบางอย่างจากฉัน แม้ว่าคุณจะบอกว่าคุณต้องการคำแนะนำเพียงชิ้นเดียว แต่โพสต์นี้เป็นรายการที่ค่อนข้างยาว ยังคงเป็นความคิดที่ดีที่จะผ่านจุดหนึ่งต่อหนึ่ง เพียงแค่เพิ่มบิตที่น่าสนใจที่คุณและโหลดด้วย~/.zshrc source ~/.zshrcเคล็ดลับสุดท้าย: เรียนรู้การกดแป้นพิมพ์ของzsh's เริ่มต้น ( 'Emacs') ^A ^E ^W Alt-F Alt-B Alt-P ^L ^Rแป้นพิมพ์ลัด: คุณสามารถแทนที่Altสองการกดแป้นพิมพ์เฉพาะกิจการ: เทียบเท่ากับAlt-PESC P


สิ่งนี้จะช่วยให้คุณเติมแท็บได้มากขึ้น

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

เปิดใช้งานการขยายแบบวงกลมทุกประเภทเช่น 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] %n@%m:%~# '

แสดงสถิติการใช้งาน CPU สำหรับคำสั่งที่ใช้เวลานานกว่า 10 วินาที

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}'
}

6
+1 สำหรับการเป็นประโยชน์ -1 สำหรับผู้สนับสนุน emac ที่แอบแฝง!
Triptych

2
คุณอาจชอบ [ github.com/robbyrussell/oh-my-zshonymous(oh-my-zsh)ซึ่งเพิ่มปลั๊กอินจำนวนมากลงใน zsh
RedPixel

14

ฉันจะแนะนำหนังสือจากทุบตีถึง Z เชลล์ มันมีคำแนะนำทั้งหมดที่คุณต้องการสำหรับการเปลี่ยนเชลล์ของคุณ มันอธิบายความแตกต่างของเปลือกหอยทั้งสองและทำให้ง่ายขึ้นสำหรับ zsher ใหม่


หนังสือเล่มนี้เป็นหนังสือที่ยอดเยี่ยมสำหรับผู้ใช้ bash และ zsh คุณต้องรักว่าแต่ละบทเริ่มต้นด้วย "ทั้ง bash และ zsh สามารถทำสิ่งนี้ได้ทั้งหมด" จากนั้นนำไปสู่อีก 30 หน้าของ "และนี่คือสิ่ง zsh เท่านั้น"
Rick

8

นี่คือ. zshrcของฉันและนั่นคือสิ่งที่สำคัญที่สุด! zsh มีจำนวนมากของตัวเลือกที่คุณสามารถใช้เพื่อดูบางตัวอย่างทั่วเน็ตหรืออ่านเอกสารที่หน้าแรกของ zsh

. zshrc ของฉันไม่มีสิ่งที่ยอดเยี่ยมอื่น ๆ นอกเหนือจากการประทับเวลาที่ด้านขวาของบรรทัดคำสั่ง

Btw อย่าลืมลอง 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/

หลังจากได้รับรายการคุณสามารถกดแท็บอีกครั้งเพื่อหมุนเวียนไปตามความเป็นไปได้ต่างๆ

แต่ได้รับคำเตือนเปลือกนี้จะทำให้คุณขี้เกียจและทำให้คุณรู้สึกว่าเปลือกมาตรฐานนั้นโง่และน่ารำคาญ!


5

คู่ที่มีประโยชน์โดยเฉพาะ globs ขยาย:

1- rmdir *(/^F)- ลบไดเรกทอรีที่ไม่ว่างเปล่าทั้งหมดภายใต้ไดเรกทอรีปัจจุบัน

2- grep traceback /srv/log/**/*(.m-2)- ค้นหา regex นี้ในไฟล์ที่แก้ไขในสองวันที่ผ่านมา

3- chmod g+w **/*(U^I)- สร้างไฟล์ใด ๆ ที่ฉันเป็นเจ้าของและไม่สามารถเขียนเป็นกลุ่มได้

ใช่แน่นอนคุณสามารถเขียนสิ่งนี้ด้วยfindแต่สิ่งนี้ง่ายกว่าที่จะรีบออกไป มันมีสองข้อเสียคือยุติธรรมทั้งที่เกี่ยวข้องกับพวกมันทั้งหมดถูกขยายไปยังบรรทัดคำสั่ง: ถ้ามันตรงกับไฟล์หลายพันไฟล์บรรทัดคำสั่งจะยาวเกินไปและสิ่งนี้จะล้มเหลวและพบไฟล์ทั้งหมดเป็นอันดับที่สอง ก่อนที่ไฟล์จะเริ่มทำงาน

(คุณจะต้องใช้setopt extendedglobหากยังไม่ได้เปิดใช้งาน)


4

ฉันไม่รู้มากเกี่ยวกับ bash ดังนั้นฉันจึงไม่สามารถคำนวณได้ ตัวอย่างบางส่วนจากไฟล์ zsh 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='*?_-[]~\!#$%^(){}<>|`@#$%^*()+:?'

คอมไพล์ในพรอมต์

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 / ฟังก์ชั่น

The 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 git@github.com style url.]"
}

_github_track() {
  _arguments \
    "--private[Use git@github.com: 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.]"
}

3

ฉันอยู่ในการเดินทางเดียวกัน :)

จนถึงตอนนี้ฉันได้พบว่าสิ่งนี้คือการมีไฟล์การกำหนดค่าที่ดี (.zshrc)

ใช้อันนี้เป็นตัวอย่างhttp://matt.blissett.me.uk/linux/zsh/zshrc , ดูความคิดเห็นและแฮ็คทางของคุณ Stackoverflow และ Severphault และสถานที่ที่ดีในการค้นหาด้วย

ฉันยังไม่ได้ดำน้ำในhttp://dotfiles.org/.zshrcแต่ฉันไม่มีเวลามากพอที่จะคลาย :)


3

เรียนรู้เกี่ยวกับการขยายตัวแบบวงกลมและการซ้ำแบบซ้ำ ๆ ใน zsh

เรียนรู้เล็ก ๆ น้อย ๆ เกี่ยวกับ zstyle และความหลากหลายของสิ่งต่าง ๆ

มองเข้าไปในอาร์เรย์ที่เชื่อมโยง นอกจากนี้อาร์เรย์มาตรฐาน (ระวังความแตกต่างจาก bash ให้ดีขึ้น!)

หากคุณใช้นิพจน์ทั่วไปให้ดู=~(ซึ่งมี bash ด้วย) และพิจารณา:setopt rematch_pcre

หลีกเลี่ยงการเขียนสคริปต์ซึ่งขึ้นอยู่กับเวทมนตร์ของ zsh มากกว่าเล็กน้อยเพราะในขณะที่มันใช้งานได้อย่างยอดเยี่ยม zsh มักจะเป็นแบบเขียนอย่างเดียว หากคุณใช้งานมากเกินไปลองคิดดูว่าเมื่อไหร่ควรเปลี่ยนเป็นภาษาเช่น Python

Zsh มีเสน่ห์ มันเป็นด้านมืด ยินดีต้อนรับ


2

ประโยชน์ที่ยิ่งใหญ่ - การทำแท็บเสร็จสมบูรณ์อย่างยอดเยี่ยมพร้อมสคริปต์สคริปต์เสร็จสิ้นการบรรจุล่วงหน้าสำหรับคำสั่งมากมาย นี่คือตัวอย่างที่แสดงผลลัพธ์ของapt-get<TAB>:

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

1

ฉันให้คูเป้ของการพูดคุยและแปลงคนหลายคนให้เป็น zsh ฉันเก็บ repo github ของบันทึกย่อของฉัน (อะไรคือข้อดี) พร้อมทั้งผู้เริ่มต้นและสำเนาของการกำหนดค่า zsh ของฉันเองใน gitub ที่นี่

http://github.com/mitechie/zshrc


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.