おもてなしの空間 このページをアンテナに追加 RSSフィード





このページの情報が多少なりとお役に立てれば、相応の寄付を頂けますと励みになります。 ソフトウエアの改訂や機能追加などのご依頼があれば、寄付をはずんでいただけますと、その気になるかもしれません。(無保証です)
寄付のお願い
メッセージ

2006年08月04日(金)

amt2006-08-04

[] bash -> zsh 移行レポート

●背景

春くらいに zshマルチバイト文字に正式対応したので、zsh に移行しない理由は何もなくなったので、思いきって zsh に移行してみた。

マニュアル

zsh は長い歴史のある素晴しいソフトなんだが、全然普及しないのは、ドキュメントの出来がひどいからだろう。

仕様集という感じでまとまっておらず、デンマーク人が書いているからか、とても英語とは思えない個所も多々あり(俺なんからヒトのことはいえんが)とにかく読みにくい。

作業に入る前に三日程眺めたが、zsh に関しては、マニュアルは読むものではなく、リファレンスマニュアル的に引くだけのものと考えた方がいい。

●結論

結論からいうと、移行作業は、拍子抜けするくらい楽だった。こんなことだったら、もっと早くに移行すべきだった。

  • .bash_profile -> .zprofile は実質的な変更個所なし
  • .zshrc は初回起動時の設定支援ソフトが生成する記述に、.bashrc の記述を適宜足すだけ
    • 通らなかったのは、プロンプト文字列(のエスケープシーケンス)だけ
  • Ver4 の compsys は、デフォールト設定そのままでもびっくりする程賢い

● .zshrc の設定

○ compinstall の作ってくれる設定雛形

初回起動時に、compinstall が、対話的に .zshrc の雛形をつくってくれる、ここは、特に気になるものがなければ、キーバインド以外は全部デフォールトでいいんじゃないかと思う。

僕の場合は、下のようなものを作ってくれた。

# Lines configured by zsh-newuser-install
HISTFILE=~/.histfile
HISTSIZE=10000
SAVEHIST=10000
bindkey -e
# End of lines configured by zsh-newuser-install
# The following lines were added by compinstall
zstyle :compinstall filename '/home/amt/.zshrc'

autoload -Uz compinit
compinit
# End of lines added by compinstall

これだけで、 Ver 3 までは大変だった、補完設定もけっこう使えるようになる。

オプションの設定

僕は マニュアルのオプションの項目 を眺めながら、とりあえず気になるものを設定してみた。

広瀬雄二さんのお薦めが ここ にあるので、僕はそれも参考にした。

###
# Set shell options
###
# 広瀬雄二さんのお薦めオプション
# http://www.gentei.org/~yuuji/rec/pc/intro-zsh.html
# setopt auto_menu auto_cd correct auto_name_dirs auto_remove_slash
# setopt extended_history hist_ignore_dups hist_ignore_space prompt_subst
# setopt pushd_ignore_dups rm_star_silent sun_keyboard_hack
# setopt extended_glob list_types no_beep always_last_prompt
# setopt cdable_vars sh_word_split auto_param_keys

# 以下、広瀬レコメンドは小文字、そうでないのは大文字にしてある
setopt auto_cd 			# コマンドが省略されていたら cd とみなす
setopt AUTO_PUSHD		# cd 時にOldDir を自動的にスタックに積む
setopt correct			# コマンドのスペルチェック
setopt auto_name_dirs		# よく判らん
setopt auto_remove_slash	# 補完が/で終って、つぎが、語分割子か/かコマンド
				# の後(; とか & )だったら、補完末尾の/を取る
setopt extended_history 	# ヒストリに時刻情報もつける
setopt extended_glob		# グロブで、特殊文字"#,~,^"を使う、
setopt FUNCTION_ARGZERO 	#  $0 にスクリプト名/シェル関数名を格納

setopt hist_ignore_dups		# 前のコマンドと同じならヒストリに入れない
setopt hist_ignore_space	# 空白ではじまるコマンドをヒストリに保持しない
setopt HIST_IGNORE_ALL_DUPS	# 重複するヒストリを持たない
setopt HIST_NO_FUNCTIONS	# 関数定義をヒストリに入れない
setopt HIST_NO_STORE		# history コマンドをヒストリに入れない
setopt HIST_REDUCE_BLANKS	# 履歴から冗長な空白を除く
setopt MULTIOS			# 名前付きパイプ的に入出力を複数開ける
setopt NUMERIC_GLOB_SORT	# グロブの数のマッチを辞書式順じゃなくって数値の順
setopt prompt_subst		# プロンプト文字列で各種展開を行なう
setopt no_promptcr              # 改行コードで終らない出力もちゃんと出力する
setopt pushd_ignore_dups	# ディレクトリスタックに、同じディレクトリを入れない
#setopt rm_star_silent		# rm * とかするときにクエリしない
#setopt no_beep			# ZLE のエラーでビープしない
#setopt cdable_vars		# cd の引数のdir がないとき ~をつけてみる
setopt SHARE_HISTORY		# 複数プロセスで履歴を共有
setopt SHORT_LOOPS		# loop の短縮形を許す
setopt sh_word_split		# よく判らん
setopt RC_EXPAND_PARAM		# {}をbash ライクに展開
setopt TRANSIENT_RPROMPT 	# 右プロンプトに入力がきたら消す

# Ctrl-D でログアウトするのを抑制する。
setopt  ignore_eof

# グロブがマッチしないときエラーにしない
# http://d.hatena.ne.jp/amt/20060806/ZshNoGlob
setopt null_glob

# デバッグ用 コマンドラインがどのように展開されたか表示
#setopt xtrace

# 小文字に対して大文字も補完する
# http://www.ex-machina.jp/zsh/index.cgi?FAQ%40zsh%A5%B9%A5%EC#l1
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}'

○プロンプト文字列

上述のように、.bashrc 上の記述を持ってきて、そのまま素直に動かなかったのはプロンプト文字列中に使っていたエスケープシーケンスだけ。

とりあえず下のようにしてみた。

ちなみに僕はマシン毎に前景色、端末毎に背景色を使い分けているのだが、前景が fg で、色の名前を cyan とか、コードじゃなくってヒューマンリーダブルな言葉で設定できるのはとても助かる。

プロンプトについても凝りたかったら、マニュアルプロンプト展開の項 は読む値打ちがある。

# プロンプトの設定
case "$TERM" in
    dumb*|emacs*) # ダム端末では色を出さないし、右プロンプトも出ない
	PROMPT="%m[%h]%# "
	#RPROMPT=" [%(5~,%-2~/.../%2~,%~)]${WINDOW:+"[$WINDOW]"}"	
	;;
    *) 
	autoload -U colors  ; colors
	PROMPT="%{$fg[cyan]%}%m[%h]%#%{$reset_color%} "
	RPROMPT="%{$fg[cyan]%}[%(5~,%-2~/.../%2~,%~)]${WINDOW:+"[$WINDOW]"}%{$reset_color%} "
	;;
esac

あと、screenウインドウ名をダイナミックに抽出するのに screen の info に書いてある手順だと、プロンプトにそれ用のエスケープシーケンスを仕込むんだけれど、これも動かなくなった。

これも、上述の Phil!'s ZSH Prompt で示されている方法を以下のようにそのままパクって回避。

いちいち解説しないけど、これってとっても巧妙なコード

preexec () {
    if [[ "$TERM" == "screen" ]]; then
	local CMD=${1[(wr)^(*=*|sudo|-*)]}
	echo -ne "\ek$CMD\e\\"
    fi
}
ディレクトリスタック

シェルディレクトリスタックって、そのままじゃ使いものにならんユーザインタフェースだと思うけれど、 zsh は、オプション設定でディレクトリ移動毎にスタックに自動的にプッシュしたり、重複するものはかたずけたりする機能がある。

それに加えて、ここに、ディレクトリスタックを表示して、その中から選んでディレクトリ移動するスクリプトがある、これらを組み合わせると、ディレクトリスタックも、ちゃんと使いものになるものになる。

#20060803 
# ディレクトリスタックからディレクトリを選ぶ
#http://www.ayu.ics.keio.ac.jp/~mukai/tips/zshdir.html
alias gd='dirs -v; echo -n "select number: "; read newdir; cd +"$newdir'

●その他の修正

僕の環境の場合 screen + zsh + emacs -nwemacs日本語が文字化けしてしまった。

下のように、terminal-coding-system を明に設定してやると解決

(set-terminal-coding-system 'utf-8-unix)

●感想など

zsh は、コマンドラインインタプリタとして決定版であるばかりでなく、プログラミング言語としても面白い存在である。

連想リストも使えるし、正規表現とは違った方向に拡張されたグロブもつかえるし、プロファイラまである。

このブログでも、これから晒してみる機会があると思う。

●不具合記録

※ 20060706 追記

使っていると、矢張り自作シェルスクリプトや .zshrc 中のシェル関数なんかで、次々と微妙な不具合がでてきた。

マッチするパターンがない時のグロブの動作

20060806の日記に詳しく書いたけれど、なんと恐しいことに、zshデフォールトの状態で、グロブのファイル名展開のときに、マッチするファイルがないと失敗する。どういうことかというと、↓のようにした場合、*.nofile にマッチするファイルがないと、ls に渡る前、グロブ展開した瞬間にエラーになって終了してしまう。だからエラーメッセージも /dev/null にいかずに、↓のようにしてもエラーメッセージも表示される。

で、だ、スクリプト中にグロブ展開して空振り(マッチするものがなかったら)、そこでエラーを起してスクリプトが停止してしまうんだ。(これって俺にはとっても難解なバグだった)

% ls *.nofile 2> /dev/null

この問題は、setopt nonomatch してやると sh/bash 同様の動作になってくれるんだが、このオプションも、オプションのネーミング規約からすると反則なんだな。

この問題は、zsh は、オプション設定によって非常に大きく動作が変ってしまうということも教えてくれる。だから、配布を想定している zsh スクリプトの先頭行には絶対↓のように -f(NO_RCS /etc/zshenv 以外の設定ファイルを読まない) が必要だ、ということが理解できた。

#! /usr/bin/zsh -f
引数の有無の判定条件

僕は bash では、引数の有無の判定をするときに次のように if 条件部に $* を直接置いていた。

hatena () {
if  $* 
    then /usr/bin/w3m "http://d.hatena.ne.jp/amt/" 
else
    /usr/bin/w3m "http://d.hatena.ne.jp/amt/archive?word="$*"&hl=ja" 
fi
}

bash では、これは僕の期待とおり、引数有無判定として動作する。が、これが正しいかどうかは、あまり深く考えたことがなかった。たまたま動いていたから使っていた訳だが、後述のようにちゃんと書くよりラクだから僕はこれを多用していた。(シェルは文法的に曖昧なことが多いので、、自家消費するスクリプトでは、このように深く考えずに適当に結果オーライでやっている個所は沢山あったりする。)

だが、zsh では、$* が展開された後、シェルコマンドとして実行される。!

だから、bash 上で hatena zsh としたら、コマンドインタプリタがあらわれるので、一見スクリプトが何もせずに終了したように見える。

↓のように、ちゃんと書くとちゃんと動く。

hatena () {
if  [ $# -gt 0 ]
    then /usr/bin/w3m "http://d.hatena.ne.jp/amt/" 
else
    /usr/bin/w3m "http://d.hatena.ne.jp/amt/archive?word="$*"&hl=ja" 
fi
}

教訓、理解もせずに動くだけのコードで済ましていると、結局高くつく。

85xe@mail.com85xe@mail.com 2007/02/05 16:57 <h1>Lund Yellowstone eightfold recital Asiaticizations admirer fishers </h1>

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/amt/20060804/zsh

[http://d.hatena.ne.jp/amt/mobile/:barcode]
■--このページについて--■

○日記開設以来のページビュー::4457676
○書いた人::逸見研一(いつみけんいち)
○mail::itsumi @ gmail.com
↑の@を半角に変更

○Skype(Voicemail)::itsumiken
いつみのカレンダー
いつみの進行管理New!
いつみの掲示板New!
ラジオ英会話上級公開ノート近日再編成
このページへリンクしているページ
このページを参照しているページ

アクセスログ

■--今読んでるモノ--■


※過去に読んだもののメモは こちら

■--今書いているモノ--■

external-filter-el20061224 着手
※過去に書き散らかしたものは こちら

■--謹製ソフトウエア--■

cmd2ftp20070118 公開
mininova_get20070102 改訂
del2bk20061223 改訂
Up2PB20061223 改訂
conv-el20061006 改訂!
pirate_get20060912 公開!
hatenahelper-mode.el

■--ほかのページ--■

おもてなしの空間 為替編20080428 発進!
アフィリエイト研究20061018 発進!
借りやすい消費者金融New!
中国株投資の証券会社選びNew!
おいでやすWiki
いつみの思いつき
いつみの予定
いつみのオープンノート
使ってみた Firefox extension
はてなフォトライフ(シンボリックな画像の倉庫)
del.icio.us
flickr
Orkut
Mixi
Facebook(実名で検索するとヒットします)New!

<< 2006/08 >>
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
最新コメント
■ 過去記事一覧 ■

■--お役立ち情報--■

html-helper-mode キーバインド
hatena-mode のキーバインド
はてな記法一覧
はてなダイアリー利用可能 html タグ

↓は、検索結果に、検索語に関連する広告が付いてくる検索窓です、面白いですよ

Google

. FLASH フラッシュ制作 携帯フラッシュ フラッシュゲーム