私がふだん手元で業務に使っているのは Windows や macOS なのですが、開発した Web アプリケーションやサービスをホストするために使用する運用環境は、たいてい Linux が動作しているサーバーです。
そのため、私の所属するチームの中でも、メンバーそれぞれが日常的に Linux の操作を行うのですが、他のエンジニアが Linux シェル上で操作しているのを横から見る機会があると、「そんな非効率な操作をしなくてもいいのに」と思ってしまうことがあります。
もちろん、どのように操作するかより、目的の動作が実現できること(目的のコマンドが実行されること)の方が重要です。それに、いちいち「それは非効率なやり方なのでこうした方がいい」と言うのは大きなお世話だと思うので、言わないようにしているのですが、やはり作業効率やミス防止のためには知っておいてほしいなと思う操作があります。
そんな基本的な Linux コマンドライン操作について、まとめました。
ls -l よりも ll を使う
シェルのエイリアス設定次第ですが、たいていの環境では ls -l のエイリアスとして ll を使えるよう、あらかじめデフォルトのログインスクリプトが組まれているのではないかと思います。
$ which ll
alias ll='ls -l --color=auto'
/usr/bin/ls
オプションなしの ls ではファイル名が分かるだけで、サイズも、更新日時も、ファイルのタイプも判別できないので、個人的には素の ls を利用することはあまりありません。ほとんど常に -l オプションを指定するのですが、スペースを含めて 5 文字タイプする (ls -l) よりも、同じキーを連続で 2 回押すだけ (ll) の方があらゆる意味で効率的です。
ファイル名を [Tab] キーで補完する
本当に基本的なことですが、Linux の bash では、現在のコンテキストで利用可能なファイル名を [Tab] キーで補完してくれます。
ファイル名やサブディレクトリ名、環境変数 PATH で参照されているディレクトリ(「PATH が通っている」場所)に存在する実行可能ファイルなどをコマンドラインで指定する場合は、ファイル名やパスの先頭を何文字か入力して [Tab] キーを押せば、該当するファイル名を表示させることができます。事前に ls コマンドでカレントディレクトリのファイルを一覧表示して確認してから、ファイル名をすべて手入力するような手順は必要はありません。
$ ll /usr/lo [Tab]
$ ll /usr/local/
また、[Tab] キーを 2 回入力すると、現在入力されている内容に先頭一致するファイル名を絞り込んで確認できます。
$ ll /usr/l [Tab] [Tab]
$ ll /usr/l
lib/ lib64/ libexec/ local/
カレントディレクトリを 1 つ前に戻す
あるディレクトリで一連の作業を行った後、別のディレクトリに移動して作業を行ったとします。もう一度先ほどのディレクトリに戻りたい場合は、cd コマンドでパスを指定しなくても、cd - で簡単に戻ることができます。
$ cd /var/log/httpd/
...
$ cd ~/log/
...
$ cd -
/var/log/httpd/
もう一度 cd - すれば、また直前のディレクトリに(上の例で言えば ~/log/ に)戻れます。
注意点として、この機能で戻れるディレクトリは常に 1 つ前のみです。1 つ前のディレクトリに戻ると、戻る直前のカレントディレクトリが今度は「1 つ前のカレントディレクトリ」になるので、そこでもう一度 cd - を実行しても 2 つ前のディレクトリに戻れるわけではありません。したがって、この機能を使うことを前提にするなら、ディレクトリ階層の深い位置に cd するときに 1 つずつディレクトリを cd して辿っていくような操作は必然的に避けることになります。
$ cd ~/log/
...
$ cd /
$ cd var/
$ cd log/
$ cd httpd/ # カレントディレクトリは /var/log/httpd/
$ cd -
/var/log # 1 つ前は /var/log なので、~/log/ には戻れない
cd する時は、[Tab] キーによる補完も活用しながら、1 回の操作で目的のディレクトリに直接移動するようにしましょう。その方がスマートであり、cd - で直前のディレクトリに戻れるようにもなります。
cd ~/log/
...
cd /var/log/httpd/
cd -
/home/ec2-user/log/
ホームディレクトリに戻る
ログインユーザーのホームディレクトリに戻りたい場合は、非常に簡単で、cd と入力するだけです。cd ~ とか、cd /home/ec2-user などと入力する必要はありません。
$ cd /var/run
...
$ cd
$ pwd
/home/ec2-user
history と grep よりも [Ctrl] + [R] を使う
Linux のシェルで、直前に実行したコマンドをもう一度実行したい場合、[↑] キーで簡単に表示できます。現在のログインセッションで数回前までに入力したコマンドを再実行するときは、この方式で何回か [↑] キー、[↓] キーを押して探すのが簡単かもしれません。しかし、それ以上に過去のコマンドになると、コマンド履歴から効率的に検索する方法が必要になります。
ひとつの方法は、history コマンドを使用することです。過去のコマンド履歴が時系列でコンソールに一覧表示されるので、その中から実行したいコマンドを探してコピーしたり、一覧に表示される番号を !<id> 形式で指定することでコマンドを再実行できます。
$ history
1 mkdir html/
2 exit
3 sudo yum install git
4 cd html
5 git clone https://code.example.jp/repos/codeandlife.git
6 cd codeandlife
7 git checkout topic/linux-comnand-line-tips
...
993 sudo vi /etc/httpd/conf/httpd.conf
994 sudo systemctl reload httpd
995 cd
996 exit
997 cd html/
998 git fetch
999 git merge
1000 sudo vi /etc/httpd/conf/httpd.conf
1001 history
$ !994
sudo systemctl reload httpd
実行したいコマンドラインの一部が分かっている場合は、history と grep コマンドを組み合わせることで多少効率化できます。
$ history | grep mariadb
28 sudo yum install mariadb-server
29 sudo systemctl enable mariadb
31 sudo systemctl start mariadb
360 sudo systemctl reload mariadb
$ !360
sudo systemctl reload mariadb
しかしもっと効率的なのは、[Ctrl] + [R] キーを使用することです。
bash のプロンプトで [Ctrl] + [R] キーを押すと、コマンド履歴を最新のものから遡ってインクリメンタルサーチすることができる、reverse-i-search モードに入ります。
$
(reverse-i-search)`':
reverse-i-search モードに入った後、キーボードから何文字か入力すると、入力した文字に部分一致するコマンド履歴が最新のものから優先して検索され、表示されます。
$
(reverse-i-search)`ht': sudo systemctl reload httpd
入力した文字列に一致する先頭位置が反転表示されています。
1 文字入力しただけでは、該当するコマンドが多すぎて目的とは違う履歴にヒットする可能性がありますが、2 〜 3 文字入力していくと、狙ったコマンドにたどり着くはずです。
$
(reverse-i-search)`htm': sudo vi index.html
また、[Ctrl] + [R] キーを繰り返し押すと、現在入力されている文字列に部分一致するもっと古いコマンドを検索して順に表示していくことができます。
$
(reverse-i-search)`ht': sudo vi /etc/httpd/conf/httpd.conf
目的のコマンドが見つかったら、[Enter] キーでそのコマンドを実行します。
[Ctrl] + [R] を常用するようになると、history と grep を組み合わせてコマンド履歴を検索するよりも、かなり効率的に過去のコマンドを探して実行できることに気づくはずです。これは、特定の Linux 環境で日常的に実行される多くのコマンドが、たいていは 2 〜 3 文字でユニークに区別できるという特性に基づいています。2 文字の連続するアルファベットと数字だけでも、論理的には 36 x 36 = 1,296 パターンのコマンドを区別できるわけです。3 文字であれば、46,656 パターンになります。
もちろん、多くのコマンドで共通に現れる文字を入力しても、目的のコマンドにはなかなかたどり着けません。例えば、特定のディレクトリに cd するコマンド履歴を見つけたいとき、cd と入力して [Ctrl] + [R] を連打するのは無駄です。しかし [Ctrl] + [R] 操作に慣れるにつれて、「自分の実行したいコマンドラインをユニークに区別してくれる最適な部分文字列」を考えて入力することが習慣になってきます。これが効率化のポイントです。
[Ctrl] + [A] で入力カーソルを行の先頭に移動する
[↑] キーであれ、history コマンドであれ、[Ctrl] + [R] であれ、過去に実行したコマンドを履歴から探してそのまま実行するだけでなく、一部を編集して実行し直したいケースも多くあるはずです。
そのような場合、キーボードの矢印キーを使用して編集したい位置に入力カーソルを移動しますが、移動したい先が行の先頭であれば、もっと効率的な方法があります。
[Ctrl] + [A] キーを押すと、入力カーソルを行の先頭に移動できます。
$ sudo systemctl reload httpd [Ctrl] + [A]
$ sudo systemctl reload httpd
[Ctrl] + [E] で入力カーソルを行の末尾に移動する
同様に、[Ctrl] + [E] で入力カーソルを行の末尾に移動できます。
$ sudo systemctl reload httpd [Ctrl] + [E]
$ sudo systemctl reload httpd
ところで、どうして先頭に移動するショートカットが A で、末尾に移動するショートカットが E なのでしょうか。本当の経緯は調べたことがないのですが、私自身は、「A はアルファベットの先頭の文字」「E は End の E」と覚えています。
まとめ
Linux のシェル上でコマンドライン操作する際、知っていれば効率的になるいくつかの方法を紹介しました。
- ls -l よりも ll を使う
- ファイル名を [Tab] キーで補完する
- カレントディレクトリを 1 つ前に戻す
- ホームディレクトリに戻る
- history と grep よりも [Ctrl] + [R] を使う
- [Ctrl] + [A] で入力カーソルを行の先頭に移動する
- [Ctrl] + [E] で入力カーソルを行の末尾に移動する
シェルとコマンドラインの世界は奥深く、歴戦のエンジニアの操作を見ていると、いったい何をどうやって操作しているのだろうと驚嘆することも多いのですが、こうした基本的な操作を覚えるだけでも、コマンドラインの操作はかなり快適になるといえます。
効率的で、かつ覚えるのも簡単な操作が他にもあれば、追記していきたいと思います。