もっと便利にBash再入門
「ソフトウェア開発でこれがないと仕事にならないソフトウェアを挙げてください。」
この答えに統合開発環境(IDE)を挙げる方が多いかと思います。それ以外にもGit、使い慣れたエディタ、使い慣れたスクリプト言語、プロジェクト(タスク)管理ツール、モデリングツールなどが上位に来るのではないでしょうか?
筆者はシェル(Bash)に一票を入れたいと思います。前述したものが主役とすると、シェルは脇役で縁の下の力持ちのようなソフトウェアです。またソフトウェア開発では必須のツールです。
Bash は筆者が良く利用するシェルです。Windows ではコマンドプロンプト(今は PowerShell でしょうか)がシェルになります。コマンドプロンプトを使ったことがあれば Bash もすぐに使えるようになりますが、コマンドプロンプトと同じ使い方をするのはちょっともったいないです。
この記事では Bash のショートカットキーや便利な使い方を紹介します。
Windows で Bash を試したい場合は Git Bash (Git for Windowsをインストールすると Bash もインストールされます) か WSL2上のUbuntuを利用するのが簡単かと思います。
なぜ Bash か?
#プログラミング言語、フレームワーク、ライブラリ、開発環境、エディタなどは目まぐるしく世代交代がありましたが、Bash は30年以上の歴史があり、現在でも利用頻度の高いソフトウェアの1つです。
普段何気なく使っている Bash ですがLinux系ではデフォルトのシェルであることが多く、おそらく5年後、10年後も使い続けられるかと思います。効率良く入力できれば、より楽しく迅速に開発ができると思います。
組み込み機器では CPUリソース、ファイルシステム容量、メモリーサイズ等に制限があります。そこで利用される組み込み系 Linux のシェルには BusyBox を使うことがあります。Bash と操作体系が似ており、Bash と思い込んでいたら実は BusyBox だったことがちらほら。
普通、各種コマンド(echo, cp, rm, findなど)はシェルから起動されます。しかし BusyBox は基本的なコマンドを内包しており、各種コマンドは BusyBox へのシンボリックリンクで作成されています。
こうすることで BusyBox の main 関数で第一引数名を見て各コマンドに対応する関数を実行するようになっており、プログラムサイズやファイル数を削減しています。
素早く、ミスせずに入力するにはどうすればよいか?
#答えは なるべく入力しない
ことです。
Bash は強力なコマンド編集機能がありますのでなるべくBash自身に仕事をさせるよう、Bashの編集機能の呼び出しを中心にキー入力します。
コマンド編集機能の紹介
#頻繁に利用するコマンド編集機能に焦点を絞って紹介します。
Tab補完
#ご存じ Tab
でファイル名を補完します。とりあえず Tab
を連打すれば補完され、その後の候補が一覧表示されますので、そこから対象のファイル名の1文字入力します。そしてまた Tab
連打、1文字入力、 Tab
連打、1文字入力 ... を繰り返すことでファイルを確定します。
長いファイル名やパスを入力する場合に重宝します。
ファイル名展開
#~
*
?
[xxx]
{xxx}
はファイル名に展開されます。ファイルを絞り込んだり、一度に複数のファイル操作をしたい場合に利用します。
~
ホームディレクトリのパスに展開
$ ls ~ # ホームディレクトリのファイル一覧表示
$ rm ~/tmp/file # ホームディレクトリのtmp/fileを削除
*
任意文字列を表し、マッチしたファイルに展開
$ ls *.log # .logで終わるファイル名に展開され一覧表示
$ cat file*.txt # fileで始まり.txtで終わる全ファイル名に展開され内容を表示
?
1文字を表し、マッチしたファイルに展開
$ ls file?.txt # fileの後に1文字あり、.txtで終わる全ファイル名に展開され一覧表示
$ ls image_??.png # image_で始まり後に2文字あり、.pngで終わる全ファイル名に展開され一覧表示
[xxx]
[]に記述されたいずれかの1文字を表し、マッチしたファイルに展開
$ ls file[23].txt # file2.txtかfile3.txtに展開されマッチしたファイルを一覧表示
$ ls [a-d].txt # a.txt, b.txt, c.txt, d.txt に展開されマッチしたファイルを一覧表示
{xxx}
{}に記述された複数文字列を展開し、マッチしたファイルに展開
$ ls {abc,xyz}.txt # abc.txtとxyz.txtに展開されマッチしたファイルを一覧表示
$ ls /{etc,usr} # /etcと/usrに展開されマッチしたファイルを一覧表示
これらファイル名展開はすべてを同時に記述できます。
$ ls ~/{log,usr}/image_?/my_[cde]*.{png,bmp} # 指定ディレクトリの画像を一覧表示
1文字移動
#基本の移動コマンドです。
コマンド | 説明 |
---|---|
Ctrl + F / → |
カーソルを1文字右(F orward)に移動 |
Ctrl + B / ← |
カーソルを1文字左(B ackward)に移動 |
行頭、行末移動
#行頭、行末への移動(ジャンプ)も良く使います。
コマンド | 説明 |
---|---|
Ctrl + A / Home |
カーソルを行頭(A head)に移動 |
Ctrl + E / End |
カーソルを行末(E nd)に移動 |
カーソルを行末付近から行頭付近に移動するときは、まずは行頭にジャンプし、そこから移動します。
単語移動
#単語単位で移動します。
コマンド | 説明 |
---|---|
Esc + F / Alt + F |
カーソルを1単語右に移動 |
Esc + B / Alt + B |
カーソルを1単語左に移動 |
このコマンドは使いたいところですが、キー配置が押しにくいため筆者はまったく使っていません。代替案としてキーバインドを変更する方法があります。
コピー・貼り付け
#コピー専用のコマンドはありません。貼り付けは削除したテキストを貼り付けます。
コマンド | 説明 |
---|---|
Ctrl + Y |
前回削除したテキストをカーソル位置に挿入 |
削除
#削除系コマンドは豊富にあり、どれもよく利用します。
コマンド | 説明 |
---|---|
Ctrl + H / Back Space |
カーソル位置の1つ前の文字を削除 |
Ctrl + D / Delete |
カーソル位置の文字を削除 |
Ctrl + U |
カーソル位置の1つ前から行頭まで削除 |
Ctrl + K |
カーソル位置から行末まで削除 |
Ctrl + W |
カーソル位置から左方向に1単語削除 |
cp long/file/path long/file/path2
を入力したいときの例
#- 元ファイル名を補完で入力する
- 元ファイル名の先頭にカーソルを移動して
Ctrl
+K
でファイル名をいったん削除する Ctrl
+Y
を2回実施して貼り付ける- 変更後のファイル名を修正する
履歴呼び出し
#コマンド履歴はBashを終了してもホームディレクトリの .bash_history
ファイルに保存されます。
そのため、過去の古いコマンドも呼び出すことができます。
コマンド | 説明 |
---|---|
Ctrl + P / ↑ |
履歴から前回のコマンドを呼び出す |
Ctrl + N / ↓ |
履歴から次のコマンドを呼び出す |
Ctrl + R |
履歴から逆インクリメンタル検索でコマンドを検索する |
Ctrl
+ P
でどんどん履歴を辿ることができます。コマンド履歴を遡れば数日前に実行したコマンドを呼び出すこともできますが、実行したコマンドを一体どれだけ戻ればいいのか探すのが大変です。
そこで便利なのが筆者イチオシのコマンド Ctrl
+ R
です。 Ctrl
+ R
を押した後でコマンドの断片(パラメータの一部分でもいい)を入力するとマッチするコマンドを履歴の新しい方から古い方へ逆に向かってインクリメンタル検索します。
以下のようなコマンド履歴があったとします。(コマンドは適当です)
$ history
1 ls
2 python test.py param1
3 python test.py param2 abc
4 python test.py param2 def
5 cp log/file1.log backup
6 ls
7 python test.py param3 abc
8 pac
9 ppp
$
ここで Ctrl
+ R
を実行するとプロンプトが以下のようになり、逆インクリメンタル検索の入力を促されます。
(reverse-i-search)`':
ここで param2
と入力すると
(reverse-i-search)`p': ppp
(reverse-i-search)`pa': pac
(reverse-i-search)`par': python test.py param3
(reverse-i-search)`para': python test.py param3
(reverse-i-search)`param': python test.py param3
(reverse-i-search)`param2': python test.py param2 def
のようにコマンド履歴の新しいものから古いものへ、コマンドの右側から左側を順に検索し、部分マッチした最初のコマンドを1つ表示します。
ここで Enter
を押せば python test.py param2 def が実行されます。
あるいはさらに Ctrl
+ R
を押すとparam2にマッチする次に古い履歴を検索して python test.py param2 abc が表示されます。
(reverse-i-search)`param2': python test.py param2 abc
なお、上記の場合、最短で Ctrl
+ R
2 a
と入力(このような入力はあまりしないとは思いますが)しておけばマッチしますのでキータッチ5回(検索文字は3文字)で履歴を辿れます。
history
と入力すればコマンド履歴が番号とともに昇順で表示されます。そこで目的のコマンドを見つけて
$ !番号
とすることで番号に対応するコマンドを実行できます。
コマンド履歴数はデフォルトでは500件や1000件となっています。 .bashrc
に
HISTSIZE=10000
などと追記しておけば履歴数を増やすことができます。
Ctrl
+ キー って面倒じゃない?
#こんな声が聞こえてきます。
「1文字消すのは Delete
や Back Space
、履歴は ↑
↓
とかの方が簡単に押せるでしょ?」
「 Ctrl
+ キー って両手使うし面倒じゃない?」
キー入力数で言えばそうなのですが、ホームポジションから指が離れてしまいます。
- 大きく手首を動かす
- 入力する
- 手首を戻す
- ホームポジション(Fキー、Jキーのポッチ)を探す
これらの動作で若干の手間が発生します。
Ctrl
+ キー であれば常にホームポジションを軸にどれかの指が乗っているためズレませんし、手首がほとんど動きません。
また、カーソルキーなどはキーボードのレイアウトにより位置が大きく変化しますが、Ctrl
や アルファベット キー はキーボードを選ばず位置は不変のため初めて使うキーボードでもすぐに入力できます。
Windows での コピペショートカット Ctrl
+ C
, Ctrl
+ X
, Ctrl
+ V
と同じで慣れればすぐに使いこなすことができます。
Bash は Ctrl
キーを多用します。 Ctrl
は左下配置されていると押しにくいため筆者はソフトウェアで Caps Lock
キー を Ctrl
キーとして認識するようにして使っています。また合わせて左の小指は A
ではなく 常に Ctrl
キー上(元のCaps Lock
キー)においています。
とは言え、本記事作成時のようなマウスを使う頻度が高い場合、ホームポジションから離れることが多いためコマンド履歴は ↑
で戻ることが多いです😀
Bash の沼
#Bashのコマンド編集機能を紹介してきましたが、ほんの一部の機能にすぎません。
- コマンドを
|
(パイプ)でつなげて処理する >
<
などで標準入出力先を切り替える- エイリアスでコマンドを短縮入力する
- シェルスクリプトで自動化
- 変数操作
- 正規表現
- ヒアドキュメント
- プロセス制御
- キーバインドの変更
など多くの機能を有しており便利な機能がたくさんあります。その沼を探索するには広すぎる(学習コストが掛かります)ため、まずはコマンド編集機能から実施してみるのがよいと思います。
チートシート
#チートシートを作ってみました。ぜひご利用ください。