ククログ

株式会社クリアコード > ククログ > lessの既定のオプションを変えて快適なCLI生活を手に入れる

lessの既定のオプションを変えて快適なCLI生活を手に入れる

その時表示している内容を消さずにlessを終了するには?

何かのコマンドの実行結果が長くなって画面外に溢れてしまう場合でも、grep ... | less という風にパイプライン経由でlessコマンドに結果を渡すと、結果を自由にスクロールしながら落ち着いてゆっくり読むことができます。

しかし、「q」でlessを終了すると、その時表示されていた内容は画面から消えてしまいます。コマンドの出力結果を見ながら次の作業をしようと思うと、以下のような工夫をしないといけません。

  • Ctrl-Zでlessをバックグラウンドに切り替えて、また参照したくなったらその都度fgコマンドで復帰させる。

  • tmuxなどのターミナルマルチプレクサを使い、画面を分割して片方の画面でlessの結果を表示しながら、もう片方の画面で操作を行う。

  • コマンドの出力を直接lessに渡して表示するのではなく、一旦リダイレクトでファイルに保存して、改めて必要に応じlessでファイルを開く。

ただ、毎度こういった工夫をするのは面倒です。

そこで便利なのが、lessの起動オプションの1つである--no-init(または-X)です。このオプションを指定してlessを起動すると、topを終了したときのようにその時の表示内容が画面上に残ったままになるため、それを参照しながら次の操作を行うことができます。

常に--no-initが指定された状態でlessを起動するには?

このように便利な--no-initオプションですが、毎回このオプションを指定するというのはあまり現実的ではないでしょう。そこで便利なのが環境変数LESSです。lessLESSという名前の環境変数に指定されている内容を規定のオプションとして自動的に使用するため、~/.bashrc~/.profileなどに以下のように書いておけば、単にコマンド名をlessと入力するだけで、lessを常に--no-initオプションありの状態で起動できるようになります。

export LESS='--no-init'

察しの良い方はもうお気づきかもしれませんが、ここには--no-init意外にも様々なオプションを併せて指定しておけます。他にも便利なオプションとしてお薦めなのは--shift-#)でしょう。これは左右カーソルによる横スクロールの速度を変えるもので、既定の状態では画面半分ずつ一気に横スクロールするのに対し、--shift 4のように小さめの値を明示しておけば、スクロール速度がなだらかになるため、見ていた箇所を見失う事もなくなります。

export LESS='--no-init --shift 4'

また、--LONG-PROMPT(または-M)というオプションを使うと、現在表示されているのが何行目から何行目までの範囲なのかが画面の下端に表示されるようになります。何行目あたりを見ているかが分かると、lessで内容を大雑把に確認してからvimなどで編集するということもやりやすくなりますので、これもお薦めのオプションです。

export LESS='--no-init --shift 4 --LONG-PROMPT'

git diffgit logで起動される時のlessの挙動を元に戻す

ここまでの話で終わらせても良いのですが、これをそのまま実施すると、ソフトウェア開発者の方などでgitコマンドを多用する場合に困ったことが起こります。それは、git loggit diffgit grepといった操作で自動的に起動されるlessの挙動が変わってしまうということです。具体的には、以下のような問題が起こります。

  • 結果が1画面内に収まるような場合(git diffの差分が小さかった場合や、git grepで見つかった件数が少なかった場合など)でもlessが起動してしまって、いちいち手動操作で「q」キーでlessを終了しなくてはならなくなる。

  • 結果の中にESC[33mのようなゴミが混ざるようになる。

これは何故なのでしょうか。

gitlessを起動する時の既定のオプション

実は、gitコマンドには自動的にlessを起動する場面用の既定のオプションが埋め込まれています。これはMakefileの中で以下のように定義されています。

ifndef PAGER_ENV
PAGER_ENV = LESS=FRX LV=-c
endif

ここでのLESS=FRXというのがそうで、これがgitコマンドの起動時に実行されるスクリプトの中

for vardef in @@PAGER_ENV@@
do
	var=${vardef%%=*}
	eval ": \"\${$vardef}\" && export $var"
done

という箇所に埋め込まれて、最終的に: "${LESS=FRX}" && export LESSというコマンドが実行されることで、「環境変数LESSで何かオプションが指定されていればそれをそのまま使い、無ければ既定のオプションとしてFRXを使う」という事が行われています。

FRX-F -R -Xの短縮表記で、それぞれロングオプションで書き表すと--quit-if-one-screen --RAW-CONTROL-CHARS --no-initとなります。

--quit-if-one-screen-F)は、前述の1つ目の問題(結果が1画面内に収まるような場合でもlessが起動してしまう)を解消するための指定です。このオプションが指定されていると、lessは表示した内容が1画面内に収まる場合にそのまま自動終了するようになります。これと--no-init-X)の併用により、あたかも「結果が長い時だけlessが起動され、結果が短い時はlessを使わずそのまま出力される」かのような挙動になっていたというわけです。

--RAW-CONTROL-CHARS-R)は、2つ目の問題(ESC[33mのようなゴミが混ざる)を解消する指定です。実はESC[33mなどのゴミのように見える文字列は文字の表示色を変えるための制御コードで、--RAW-CONTROL-CHARSオプションが指定された場合、lessはこの制御コードに基づいて文字の色変えや強調表示を行うようになります。

gitから起動されるlessの挙動を戻す2つの方法

以上の事を踏まえて、git diffgit grepの時のlessの挙動を元に戻す方法は2通り考えられます。

1つは、不足していたオプションを環境変数LESSで指定するようにする方法です。

export LESS='--no-init --shift 4 --LONG-PROMPT --RAW-CONTROL-CHARS --quit-if-one-screen'

lessの既定の挙動が全般的に変わってしまっても問題なければ、これが一番簡単でしょう。

全般的な既定の挙動を変えずにgitから起動された時の挙動だけを変えたい場合は、git configでこれらのオプションを加えた状態のlessをページャとして明示的に設定するという方法があります。

$ git config --global core.pager 'less --RAW-CONTROL-CHARS --quit-if-one-screen'

この場合、gitから起動されたlessはここで指定されたオプションと環境変数LESSで指定されたオプションの効果がマージされた挙動となります。

まとめ

以上、lessの既定のオプションの指定の仕方とお薦めの設定、そしてgitとの組み合わせでの注意点をご紹介しました。

lessにはここで登場した物以外にも様々なオプションがあります。man lessを見ながら必要なオプションを環境変数LESSに設定して、普段の作業効率の向上に繋げてください。