zshのtips
インストール
osx
$ brew install zsh
デフォルトのshellをzshにする
$ chsh -s $(which zsh)
- rootユーザでこの変更を行うのはrootでログインできなくなる可能性があり、リスクである
プラグインで機能を拡張する
antigen
- 依存が少ないプラグインマネージャ
インストール
$ curl -L git.io/antigen > antigen
$ source ~/antigen # .zshrcの中で読み込む
プラグインのインストール
antigen bundle <plugin-name>
zsh-autosuggestions
- hisotryの中から同じ文字で始まるコマンドと引数をレコメンドしてくれる
インストール
antigen bundle zsh-users/zsh-autosuggestions
必要に応じてbitbucketに.zshrc
を更新して管理する
キーバインド
デフォルトのよく使う設定
-
"^[^?"
: backward-kill-word-
alt + delete
でカーソルの後ろのワードを削除(argumentの一つを消す)
-
設定されたキーバインドを確認する
$ bindkey
特定の機能をバインドする
# Alt+wで次の単語へ
bindkey "∑" forward-word
# Alt+bで前の単語へ
bindkey "∫" backward-word
# Alt+→で次の単語へ
bindkey "^[[1;3C" forward-word
# Alt+←で次の単語へ
bindkey "^[[1;3D" backward-word
# Alt+aでautosuggest-accept
bindkey "å" autosuggest-accept
-
alt + arrow
で前か次の単語へ移動できる
zshの構文と具体例
ヒアドキュメントでzshを動かす
$ zsh -f
複数のコマンドの実行
;
- 左のコマンドが正常に実行できてもできなくても右のコマンドを実行
&&
- 左のコマンドが正常に実行できた時、右のコマンドを実行する
||
- 左のコマンドが正常に実行できない時、右のコマンドを実行する
シングルクオートとダブルクオートの違い
- シングルクオート
- シェル変数を内部で展開しない
- ダブルクオート
- シェル変数を内部で展開する
インターネット上にあるzshスクリプトを読み込む
ダウンロード場所を指定しておき、存在しなれけば読み込む
# gistによる機能拡張
function load_remote_zshrc() {
# 1. .tmpが存在しなかったら作成
# 2. .tmp/zshrcが存在しなかったらダウンロード
if [[ ! -d ~/.tmp ]]; then
echo "create local .tmp directry."
mkdir ~/.tmp
fi
if [[ ! -f ~/.tmp/zshrc ]]; then
echo "create local .tmp directry."
curl -o ~/.tmp/zshrc https://gist.githubusercontent.com/GINK03/e96cf8fa45a5c97846d5b6cb362d5ce7/raw/zshrc
fi
source ~/.tmp/zshrc
}
load_remote_zshrc
関数を定義して呼び出す
# 定義
# rf <filename>
function rf {
# 必須な引数
readonly file_name=${1:?"rgで検索するファイル名の引数"}
rg --files | rg $file_name # ラップしたコマンド
}
# 呼び出し
rf "hoge"
if文
if [[ "$PARAM" = "master" ]]; then
echo "これはmaster"
elif [[ "$PARAM" = "main" ]]; then
echo "これはmain"
else
echo "これはFalse"
fi
- 必ず、
[[
のあとにはspace一個、]]
の前にspace一個が必要
ディレクトリがあるかどうかのチェック
if [[ -d ~/.tmp ]]; then
echo "存在する"
else
echo "存在しない"
fi
ファイルがあるかどうかのチェック
if [[ -f ~/target_file ]]; then
echo "存在する"
else
echo "存在しない"
fi
シンボリックリンクがあるかどうかのチェック
if [[ -L ~/.zshrc ]]; then
echo "存在する"
else
echo "存在しない"
fi
特定のコマンドが存在するかのチェック
この例ではlsb_release
が存在するかの確認
which
ではalias
が設定されているときは正しくハンドルされないので、type
のほうが汎用性がある
if type "lsb_release" > /dev/null; then
echo "存在する"
fi
for文
for bin in peco vim nvim tmux
do
echo $bin
done
- peco, vim, nvim, tmuxがそれぞれ改行されて出力される
names=("山田" "田中" "斎藤")
for name in ${names[@]}; do
echo $name
done
"""
山田
田中
斎藤
"""
case文
例えばOSで処理を分けるとき
case `uname` in
Darwin)
echo "MacOSX"
;;
Linux)
echo "Linux"
esac
プログラムの異常終了をキャッチする
$ echo $?
1
-
0
のとき正常 -
1
のとき異常 - その他のとき何らかのソフトウェアごとに予約された動作
stringをsplitしてリストにする
# spaceで分割する
string="aaa bbb ccc ddd"
parts=(${(@s: :)string})
echo $parts[2] # bbbが出力
parts=(${(@s/ /)string})
echo $parts[2] # bbbが出力
- この記法はzshでしか動作しない(bash, shはエラー)
コマンドを実行する直前のhook、直後のhook
autoload -Uz add-zsh-hook
preexec_any_function () {
# コマンドを実行する前の関数
}
precmd_any_function () {
# コマンドを実行後の関数
}
# hookに関数を登録
add-zsh-hook preexec preexec_any_function
add-zsh-hook precmd precmd_any_function
pythonでコマンドを作る
-
.zshrc
にpythonスクリプトを記入して変数に代入する - インラインのpythonの引数に変数を与えたものにエイリアスを張る
export my_python_command_script='
import os
for arg in sys.argv[1:]:
print(f"{arg}という引数が入力されました")
'
alias my_python_command="python3 -c '$my_python_command_script'"
terminalにgitのbranchを表示する
zsh
にはvcs_info
というモジュールが存在し、gitのbranchを取得できる
precmd関数
はコマンドを打つ前に自動で走るコマンドで、この中に記すことで、コマンド度に最新のbranch情報に更新できる
autoload -U colors && colors
autoload -Uz vcs_info
zstyle ':vcs_info:*' enable git svn
zstyle ':vcs_info:git*' formats "%b"
function precmd() {
vcs_info
PS1="%{$fg[cyan]%}%n@%m%{$reset_color%}:%1 %~ (${vcs_info_msg_0_})$ "
}
setopt prompt_subst
terminalにdatetime
を表示する
PS1
のフォーマットは以下のようになる
%D{ %Y-%m-%d %M:%H:%S}
terminalを改行する
PS1
に直接\n
を書けないので、以下のように変数を作って代替する
NEWLINE=$'\n'
PS1="hogehoge ${NEWLINE} foobar"
aliasの実体を確認する
$ type -a n
n is an alias for nvim
...
aliasを解除する
sudo
, ip
などをラップしていると不整合を起こすことがあるのでそのような場合に使える
$ unalias sudo
rootユーザになる
環境によって方法が異なる
$ sudo su
または
$ sudo -s
トラブルシューティング
環境変数を適切に設定しているのに、ls
コマンド等で文字化けが起きるとき
- 原因
- 何らかの影響で
locales
パッケージが不整合を起こしていることがあった
- 何らかの影響で
- 対応
- 以下のコマンドで
ja_JP.UTF-8
に設定し直すことで治った事があった
- 以下のコマンドで
$ sudo dpkg-reconfigure locales
終端文字%
が正しくハンドルされなくて描画がずれる時
- 原因
- zshの機能の1つで終端文字をstdinがキャッチできないとき、
%
で代替する機能があり、ハンドルにミスるとterminalが崩壊する
- zshの機能の1つで終端文字をstdinがキャッチできないとき、
- 対応
-
reset
を入力する
-
$ reset
ctrl+a
, ctrl+e
でzshで移動できない(^A, ^Eが入力されてしまう)
- 原因
-
ctrl+a
,ctrl+e
がハンドルされていない
-
- 対応
-
.zshrc
と.tmux.conf
でemacsスタイルを適応すると入力できる
-
.zshrc
bindkey -e
.tmux.conf
set -g mode-keys emacs
set -g status-keys emacs
sudoしたときユーザ定義のaliasを引き継ぐ
alias sudo="sudo "
zsh compinit: insecure directories...
と警告がでる
- 原因
- zshのモジュールがセキュアな設定になっていないことが原因
- brewのzsh補完などが原因ででることがある
- 対応
- compauditで出力される内容を、ユーザonlyのパーミッションにすることで修正することができる
$ compaudit | xargs chmod g-w