Pindah dari bash ke zsh [ditutup]


143

Saya sedang mempertimbangkan pindah dari bash ke zsh karena saya sering menemukan posting memuji zsh. Saya pengguna baris perintah yang berpengalaman dan saya mengasumsikan dasar-dasarnya hampir sama, jadi saya mencari saran untuk mendapatkan manfaat bergerak, dan setiap gotcha harus diperhatikan.

Tolong, berikan sedikit saran per jawaban. Saya mencari potongan ukuran gigitan di mana saya bisa kembali dan mengintegrasikan bit info tambahan ke dalam penggunaan shell saya dengan kecepatan yang stabil daripada mencoba untuk mempelajarinya semuanya dalam sekali jalan.


8
Saya ingin tahu apakah mungkin untuk mengintegrasikan perintah-tidak-ditemukan Ubuntu dengan zsh. Saya beralih kembali ke bash karena ini (dan banyak gangguan lainnya).
Marius Gedminas


Dua tautan lebih menarik: "ZSH FAQ" zsh.sourceforge.net/FAQ & "ZSH adalah teman Anda" mikegrouchy.com/blog/zsh-is-your-friend.html
Shadok

3
@MariusGedminas: ( dari sini ) zsh memang mendukung ini, tetapi Anda harus mengaktifkannya secara manual. Tambahkan saja source /etc/zsh_command_not_foundke .zshrc.
naught101

Jawaban:


94

Seperti yang Anda katakan, zshdalam banyak hal serupa bash. Ini memiliki beberapa fitur yang tidak akan Anda temukan bash, dan dapat diperluas dengan cara yang kuat. Jangan berpikir bergerak sebagai semacam revolusi, melainkan sebagai serangkaian langkah evolusi yang membantu Anda dalam pekerjaan sehari-hari. Berikut beberapa petunjuk dari saya .zshrc. Meskipun Anda mengatakan Anda lebih suka saran tunggal, posting ini adalah daftar agak panjang. Tetap merupakan ide bagus untuk membahas poin satu per satu. Cukup tambahkan bit yang menarik ke Anda ~/.zshrcdan muat ulang source ~/.zshrc. Tip akhir: belajar keystrokes dari zsh's default ( "Emacs") shortcut keyboard: ^A ^E ^W Alt-F Alt-B Alt-P ^L ^R. Anda dapat mengganti Altdengan dua penekanan tombol yang terpisah: Alt-Psama dengan ESC P.


Ini memberi Anda penyelesaian tab yang lebih luas.

autoload -U compinit
compinit

Penyelesaian tab dari kedua ujung.

setopt completeinword

Penyelesaian tab harus peka huruf besar-kecil.

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

Penyelesaian yang lebih baik untuk killall.

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

Mengubah definisi "kata", misalnya dengan ^ W.

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

Warna untuk ls.

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

Pintasan untuk ls.

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

Satu riwayat untuk semua kerang yang terbuka; simpan 10.000 entri. Ini menjadikan ini menjadi bantuan memori yang berguna untuk menemukan perintah yang Anda gunakan terakhir kali untuk ./configuredll. Gunakan Alt-P (temukan perintah yang dimulai seperti ini) dan ^ R (cari dalam sejarah) secara bebas.

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

Mengaktifkan semua jenis globbing yang diperluas, seperti ls ** / *. Txt (temukan semua file teks), ls -d *(D)(tampilkan semua file termasuk yang dimulai dengan "."). Untuk mengetahui lebih lanjut, buka man zshexpn, bagian "GENENASI FILENAME".

# superglobs
setopt extendedglob
unsetopt caseglob

Ini berguna untuk mengingat perintah dalam riwayat Anda tanpa menjalankannya.

setopt interactivecomments # pound sign in interactive prompt

Ketik ".." bukan "cd ..", "/ usr / include" bukan "cd / usr / include".

setopt auto_cd

Nice prompt.

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

Tampilkan statistik penggunaan CPU untuk perintah yang membutuhkan waktu lebih dari 10 detik

REPORTTIME=10

Beberapa perintah yang Anda gunakan secara luas di 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'

Daftar paket yang diurutkan berdasarkan ukurannya - berguna saat memutuskan paket mana yang menggunakan ruang disk Anda.

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

6
+1 untuk berguna. -1 untuk advokasi emacs diam-diam!
Triptych

2
Anda mungkin juga menyukai [ github.com/robbyrussell/oh-my-zsh[(oh-my-zsh) yang menambahkan banyak plugin ke zsh.
RedPixel

14

Saya akan merekomendasikan buku From bash to Z Shell . Ia memiliki semua saran yang Anda butuhkan untuk mengganti shell Anda. Ini menjelaskan perbedaan kedua shell dan membuatnya mudah untuk zsher baru.


Buku ini bagus untuk pengguna bash dan zsh. Anda harus mencintai bagaimana setiap bab dimulai dengan "bash dan zsh dapat melakukan semua ini" dan kemudian mengarah ke 30 halaman lain "dan inilah satu-satunya hal zsh"
Rick

8

Ini adalah .zshrc saya dan itu adalah hal yang paling penting! zsh memiliki banyak opsi yang dapat Anda gunakan, jadi lihatlah beberapa contoh di internet atau baca dokumentasi di beranda Zsh .

.Zshrc saya tidak mengandung hal-hal keren selain timestamp di sisi kanan baris perintah.

Btw, ingatlah untuk mencoba tab-compleation di mana saja beberapa contoh di sini:

mplayer -a[tab]

akan menampilkan sesuatu seperti ini:

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

Dan jika Anda menggunakan ssh-key atau ssh-agent tanpa kata sandi, Anda mungkin menemukan manfaatnya untuk membuat file jarak jauh yang lengkap:

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

Setelah mendapatkan daftar, Anda dapat menekan tab lebih banyak untuk menelusuri berbagai kemungkinan yang berbeda.

Tetapi berhati-hatilah, cangkang ini akan membuat Anda malas dan membuat Anda merasa bahwa cangkang standar itu bodoh dan menyebalkan!


5

Beberapa gumpalan diperpanjang khusus yang berguna:

1- rmdir *(/^F)- hapus semua direktori tidak kosong di bawah direktori saat ini

2- grep traceback /srv/log/**/*(.m-2)- cari regex ini dalam file yang dimodifikasi dalam dua hari terakhir

3 chmod g+w **/*(U^I)- membuat file yang dimiliki oleh saya dan tidak dapat ditulis kelompok menjadi ditulis kelompok

Ya, tentu saja Anda dapat menulis ini dengan findtetapi ini lebih mudah untuk lari. Itu memang memiliki dua kelemahan, agar adil, keduanya harus dilakukan dengan mereka semua diperluas ke baris perintah: jika cocok dengan ribuan file baris perintah akan menjadi terlalu lama dan ini akan gagal, dan kedua semua file ditemukan sebelum file mulai berjalan.

(Anda akan perlu setopt extendedglobjika itu belum aktif)


4

Saya tidak tahu banyak tentang bash, jadi saya tidak bisa mengimbangi. Beberapa cuplikan dari file konfigurasi zsh saya.

Beberapa konfigurasi

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='*?_-[]~\!#$%^(){}<>|`@#$%^*()+:?'

Masuk dalam prompt

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

Beberapa hotkey, masukkan beberapa teks di awal baris.

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

Fungsinya, saya simpan kemudian di ~ / .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

Beberapa opsi 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

Saya di perjalanan yang sama :)

Sejauh ini saya telah menemukan bahwa masalahnya adalah memiliki file konfigurasi yang baik (.zshrc).

Ambillah yang ini sebagai contoh http://matt.blissett.me.uk/linux/zsh/zshrc , lihat komentar-komentarnya dan retas jalan Anda. Stackoverflow dan severphault dan tempat yang bagus untuk mencari juga.

Saya belum masuk ke http://dotfiles.org/.zshrc , tapi saya tidak punya banyak waktu untuk lepas :)


3

Pelajari tentang gumpalan globing yang diperluas dan rekursif di zsh.

Pelajari sedikit tentang zstyle dan bagaimana berbagai hal (terutama penyelesaian) memungkinkan Anda menyesuaikan konfigurasi menggunakan zstyle.

Lihatlah ke array asosiatif. Juga array standar (waspadalah terhadap perbedaan dari bash, menjadi lebih baik!)

Jika Anda menggunakan ekspresi reguler, lihat =~(yang dimiliki oleh bash) dan pertimbangkan:setopt rematch_pcre

Hindari menulis skrip yang bergantung pada lebih dari sedikit zsh's magic, karena walaupun sangat fantastis untuk digunakan, zsh dapat cenderung hanya menulis. Jika Anda menggunakan terlalu banyak, pikirkan kapan harus beralih ke bahasa seperti Python.

Zsh menggoda. Itu adalah sisi gelap. Selamat datang.


2

Manfaat besar - penyelesaian tab yang sangat baik dengan skrip penyelesaian pra-paket untuk banyak perintah. Berikut ini contoh yang menunjukkan output dari apt-get<TAB>:

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

1

Saya sudah memberikan banyak pembicaraan dan mengubah beberapa orang menjadi zsh. Saya menyimpan repo github dari catatan saya (apa kelebihannya) bersama dengan starter dan salinan konfigurasi zsh saya sendiri di github di sini.

http://github.com/mitechie/zshrc


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.