ラベル zsh の投稿を表示しています。 すべての投稿を表示
ラベル zsh の投稿を表示しています。 すべての投稿を表示

2021年7月11日日曜日

履歴が更新されないZ、解決編

zshのヒストリが更新されない問題の解決編。

まず、この問題自体はmacOS限定だった。もっと言うと、macOS標準のターミナル限定。そして解決方法は、~/.zshenvで

SHELL_SESSIONS_DISABLE=1

と設定する。問題の対処だけできれば十分な人は、以下は読まなくてもよし。

問題のふるまいの元は、/etc/zshrc_Apple_Terminalにあった。これはmacOS標準のターミナルでzshを実行する場合のみ、/etc/zshrcの最後にsourceされるスクリプト。この中で行われるセッション毎にヒストリを持たせる処理を、マルっとスキップさせるための変数がSHELL_SESSIONS_DISABLE。ここに0以外の値を設定しておけば、従来どおりのふるまいとなる。なお、zshrc_Apple_Terminal内のコメントには環境変数を設定しろと書いてあるけど、シェル変数で十分。

注意点として、/etc/zshrcが実行される前にSHELL_SESSIONS_DISABLEが設定されていなければならないので、~/.zshrcで設定しても間に合わない。zshrc_Apple_Terminal内のコメントにもあるとおり、~/.zshenvで設定するのが無難だろう。本当は~/.zshenvには、インタラクティブシェル用の設定を書きたくないんだけど。

なお、どう見てもMac向けのコードでライセンスが分からなかったので、このポストでは引用を避けた。Macを持ってないけど気になる人は、最寄りのMac売り場で確かめてくれ。

2021年7月8日木曜日

履歴が更新されないZ

zshのヒストリが、いつの間にか更新されていないことに気付いた。

具体的には、zsh起動中のオンメモリのヒストリは更新されるけれど、zsh終了時にヒストリがファイルに保存されない。なまじよく使うコマンドはヒストリに残っているので、今日の今日まで気付かなかったのだ。

どうやら、HISTFILEの値が上書きされてしまうようだ。~/.zshrcの中でHISTFILEを設定しているのだけれど、起動後に確認してみると

% echo $HISTFILE
/Users/xx/.zsh_sessions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.historynew

となっている。よくよくタイムスタンプを見たら、元々HISTFILEに指定していたファイルは昨秋から更新されてないじゃないか。ヒストリをロードするタイミングでは.zshrcの設定値が生きているけど、その後に設定値が上書きされてしまうので、終了時に目当てのファイルに保存されない感じか。

タイミング的には、Big Surにアップデートしたあたりでzshのバージョンと挙動が変わったのだろうか。週末にでも真面目に調べよう。

2020年3月5日木曜日

screenと.zprofile

ログインシェルは当然のようにzshにしていることは大前提で、screenで新しいwindowを作ったとき、~/.zprofileは実行されない。

…というのは、別にログインシェルを起動しているわけではないから、まあそんなもんだろうと納得できる。が、.zprofile実行済みのログインシェルからforkしたscreenからforkしたzshなら、.zprofileで設定した環境変数が引き継がれているはずじゃないのか?

何度も設定し直す必要はないと思って、.zprofileでライセンス関連の環境変数を設定していたら、screenのwindowの中では反映されないでやんの。.zshenvとかで設定を上書きしてたっけ? あとできちんと調べよう。

2020年1月16日木曜日

履歴がふっとんだZ、その後

Zshのヒストリ消失をきっかけに、今日1日SHARE_HISTORYオプションを有効にして使ってみた感想。

複数起動しているZsh間でヒストリを共有できた方が、そりゃ便利に決まっているだろう。そう思って設定したのだけれど、意外な落とし穴。あっちこっち切り替えながら使っていると、どのシェルで何の作業をしていたのか、こんがらかることスパゲッティの如し。

今まで意識していなかったけど、何を実行していたかを確認するのに、結構ヒストリを見ていたのだ。3つくらい並列でバグ修正していると、この変更を入れてからビルドしたっけ? とか、ビルドしたFWを動作確認用の開発機に送ったっけ? とか、リアルタイムでヒストリを混ぜられると、パッと分からなくなってしまうのだ。タイムスタンプを調べれば分かることは分かるんだけど、サッとヒストリをめくる方が圧倒的に楽だし。

…と言うわけで、やっぱり元に戻そうかと思いかけている。

履歴がふっとんだZ

今日は久々に朝から慌てた。メインの開発環境のZshのヒストリが、なぜだか空になってしまっていたのだ。

正直、原因は不明。screenでたくさん起動していた中の1つが、何かのはずみでSAVEHIST=0になってしまっていた? 何にせよ、今となっては確認しようがない。

Zshのヒストリは、シェルスクリプト化したりエイリアスを定義したりするほどではないけれど、ゼロからタイプするのは微妙に面倒だったり、うろ覚えだったりするコマンドの宝庫。喪失は地味に痛い。改めて、歴史を刻み直すしかないのだけど…。

これをきっかけに、man zshoptionsをざっと眺めてみた。SHARE_HISTORYなんてオプションがあって、複数起動しているZsh間でヒストリを共有できたのか。ただ、これを有効化するとヒストリのフォーマットがタイムスタンプ付きになるようで、途中から変えたらタイムスタンプありとなしが混在してしまった。大丈夫だろうか?

2015年7月4日土曜日

Cygwinの/etc/passwdは過去のものになりました

Cygwinにはchshがないので、シェルを変更するのに/etc/passwdを直接編集しようとしたら、そもそも/etc/passwdがない。どうも、Cygwinで/etc/passwdをいじるのは過去の話になったようだ。

では、その代わりにどうするのかと言うと、/etc/nsswitch.confを編集するのが今どきのCygwinの流儀だそうな。シェルを/bin/zshに変更するには、/etc/nsswitch.confに以下の1行を追加。

db_shell: /bin/zsh

もっとも、/etc/passwdがまったく無視されるわけではないらしい。こちらのQ&Aによると、標準では/etc/passwdが生成されないけど、存在すれば設定はきちんと反映されるとのこと。昔のCygwinが生成したものが残っていたり、明示的に生成したりすれば、従来通り/etc/passwdを使えるそうな。

ともあれ、これで個人的3種の神器Zsh, Ruby, VimがCygwin環境に整った。

2014年6月13日金曜日

自分は何をしていたのか?

多くのターミナルエミュレータがタブ機能をサポートしてくれているおかげで、ここ数年は目の前のプロセスをサスペンドしてpushdして…、なんてことをする代わりに、新しいタブで新しいシェルを立ち上げてしまう機会がかなり増えた。それ自体は便利で良いのだけれど、最近は頭の方が追いつかなくなってきた。しばらく離れていたタブに戻ったときに、そのタブでどんな作業をしていたのか思い出せないことがあるのだ。

シェルのヒストリやレポジトリとの差分を見れば大抵のことは思い出せるのだけど、何かもっと一目で分かるような目印を付けられないだろうか? そう考えて真っ先に思い付いたのはウィンドウタイトルの変更。ただ、既にウィンドウタイトルにはホスト名やカレントディレクトリを表示しており、慣れ親しんだPROMPTは変えたくない。さて、どうしたもんか?

で、色々ググっていたところ、自分はRPROMPTを使っていないことに気が付いた。どうせ使ってないのだから、未来の自分へのちょっとした書き置きにRPROMPTを使えばええじゃないか。

zshばかり使っているから知らなかったけど、今はbashやtcshもRPROMPTをサポートしてるのね。

2014年5月24日土曜日

zshでバッググラウンドジョブを残したままexit

zshからグラフィカルなツールを立ち上げた後、そんな子プロセスを道連れにせずに親のシェルだけexitで終了させたい。そんなときにはdisownコマンド。

zsh% xeyes &
zsh% jobs
[1] + running xeyes
zsh% disown %1
zsh% exit
こんな感じ。同様の機能の同名の内部コマンドは他のシェルにもあるので、別にzshに限った話じゃないけど。

2013年2月22日金曜日

zshでgemの引数補完

gem用のzsh補完関数がないかとさがしてみたところ、こちらを発見。早速ダウンロードして、fpathが通っているところに置いて使ってみた。

おお、やっぱり補完が効くと快適だな〜。gitとかsvnとかは、もうzshなしで使うなんて考えられない。

2012年7月12日木曜日

Macでコマンドラインからクリップボード操作

Macでコマンドラインからクリップボードにコピーしたり、クリップボードからペーストするには、pbcopy, pbpasteコマンドを使えばOK。Cygwinのputclip, getclipみたいなもの。

pbcopy
標準入力をクリップボードへコピー
pbpaste
クリップボードの内容を標準出力へ書き出し

なぜpb? と思ったら、Macではpasteboardと呼ぶのね。

ついでに、標準入力をクリップボードにコピーしながら標準エラー出力にも吐き出すzshのエイリアスを定義した。

% alias -g C='|tee /dev/stderr|pbcopy'
% echo 'how to use' C
how to use

2012年2月24日金曜日

zsh補完の小ネタ


小文字で入力しても、適宜大文字にしてくれる。
…だけではなく、'-'を適宜'_'にしてくれるzshの補完設定。
zstyle ':completion:*' matcher-list 'm:{-a-z}={_A-Z}'
かなりShiftを押さなくても済むようになる。英語キーボード派にオススメ。

2012年2月19日日曜日

Macでzsh補完時の色設定

.zshrc等をMacに持ってきて、真っ先に怒られたのがlsの色。dircolorがない。…というか、そもそもGNUのlsじゃないからLS_COLORSを設定しても効かないし、lsに色を付けるオプションも異なる。調べてみると
  1. 環境変数LSCOLORSを設定
  2. GNUのCoreutilsを入れてしまう
という手があるようだが、せっかくなので郷に従い前者を選択。詳細はmanに譲って、とりあえず好みの設定をメモ。
export LSCOLORS=gxcxfxbxdxegedabagacad
さて、これで大体OKかと思いきや、zshの補完リストに色が付かない。が、それもそのはず。
zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS}
とLS_COLORSを元に設定している。このまま無色なのは寂しいので、LSCOLORSからzsh式に変換するスクリプトを書いた。

#!/usr/bin/ruby
DefaultColors = 'exfxcxdxbxegedabagacad'
Attrs = %w(di ln so pi ex bd cd su sg tw ow)
lscolors = ENV['LSCOLORS'] || DefaultColors
codes = lscolors.scan(/../).map do |fb|
  cd = []
  cd << '01' if fb =~ /[A-H]/ # bold
  f, b = fb.downcase.scan(/./).map do |c|
    'abcdefgh'.index(c)
  end
  cd << '3%d' % f if f  # foreground
  cd << '4%d' % b if b  # background
  cd
end
zcolors = codes.zip(Attrs).map do |cd, at|
  "#{at}=#{cd.join(';')}" unless cd.empty?
end
print zcolors.compact.join(' '), "\n"
これをPATHの通った場所にzcolorという名前で置いて、
zstyle ':completion:*' list-colors $(zcolor)
と.zshrcあたりで実行しておけば、zshの補完リストにLSCOLORSと同じ色が付く。厳密にはboldの扱いがちょっと違うけど。