その時表示している内容を消さずに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
です。less
はLESS
という名前の環境変数に指定されている内容を規定のオプションとして自動的に使用するため、~/.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 diff
やgit log
で起動される時のless
の挙動を元に戻す
ここまでの話で終わらせても良いのですが、これをそのまま実施すると、ソフトウェア開発者の方などでgit
コマンドを多用する場合に困ったことが起こります。それは、git log
やgit diff
、git grep
といった操作で自動的に起動されるless
の挙動が変わってしまうということです。具体的には、以下のような問題が起こります。
-
結果が1画面内に収まるような場合(
git diff
の差分が小さかった場合や、git grep
で見つかった件数が少なかった場合など)でもless
が起動してしまって、いちいち手動操作で「q」キーでless
を終了しなくてはならなくなる。 -
結果の中に
ESC[33m
のようなゴミが混ざるようになる。
これは何故なのでしょうか。
git
がless
を起動する時の既定のオプション
実は、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 diff
やgit 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
に設定して、普段の作業効率の向上に繋げてください。