Bashの組み込みコマンド “bc” を使ってみる

2023-12-31Bash

はじめに

Bash でコマンドを実行しているときにコマンドをうち間違えたことは何度もありますよね。

間違えただけではなく、過去に実行したコマンドのスペルを忘れてしまったり、引数やオプションを忘れてしまったりも一度ならず何度もあるはずです。

Bash にはヒストリ機能があるため上矢印キーや下矢印キーで過去に実行されたコマンドの履歴をたどることができますが、 fc コマンドを利用することで過去に実行したコマンドの再利用が更にはかどります。

今回は fc コマンドの使い方について紹介します。

検証環境

$ uname -moi
aarch64 aarch64 GNU/Linux

$ head -n 3 /etc/os-release
PRETTY_NAME="Ubuntu 22.10"
NAME="Ubuntu"
VERSION_ID="22.10"

$ bash -version | head -n 1
GNU bash, バージョン 5.2.2(1)-release (aarch64-unknown-linux-gnu)

"fc" コマンドの概要

fc コマンドは、Bash の組み込みコマンドの 1 つです。
"fix command" の 2 つの単語の頭文字をとって fc コマンドと名付けられているようです。
具体的には、次のような機能を持っています。

  • 過去に実行したコマンドを一覧表示
  • 直前に実行したコマンドをエディタで編集し実行
  • 過去に実行した任意のコマンドをエディタで編集し実行
  • 過去に実行した複数のコマンドをひとまとめに実行
  • 直前に実行したコマンドを編集せずに実行

fc コマンドは Bash だけでなく、Zsh でも使用できます。
Mac OS ユーザーでも学習しておいて損はありません。

過去に実行したコマンドを一覧表示

ターミナル上の作業から一時的に離れたのち戻ってきたら何をしていたか忘れていました、なんてことがあります。
複数のコマンドを順番に 1 つ 1 つ実行していたが、どこまで実行したか忘れてしまったといったこともあります。

そんなときは落ち着いて。
fc コマンドを実行すれば何をしていたか思い出すことができます。

# 1つ目のコマンド
$ echo "first"

# 2つ目のコマンド
$ echo "second"

# スクリーンをクリア
$ clear

これまでどんな操作をしていたかわからなくなってしまいました。
(スクリーンを上にスクロールします、 screentmux を使っていればもちろんこのようなことにはなりませんが)

ここで fc -lfc コマンドを -l オプション付きで実行します。

$ fc -l
1        # 1つ目のコマンド
2        echo "first"
3        # 2つ目のコマンド
4        echo "second"
5        # スクリーンをクリア
6        clear

コメント行を含めて、今まで実行したコマンドが表示されます。

デフォルトでは履歴が 16 コマンド分しか表示されません。
-l の後ろに数値を指定すると、指定した数値に一致する履歴番号以降の履歴が全て表示されます。

55 を指定したからといって履歴が 55 コマンド分表示されるわけではないという点に注意が必要です 。

# デフォルトでは直近に実行された16コマンドが表示される
$ fc -l
45       echo 2
46       echo 3
47       echo 4
48       echo 5
49       echo 6
50       echo 7
51       echo 8
52       echo 9
53       echo 10
54       echo 11
55       echo 12
56       echo 13
57       echo 14
58       echo 15
59       echo 16
60       echo 17

# 55番目に実行されたコマンド以降が全て表示される
$ fc -l 55
55       echo 12
56       echo 13
57       echo 14
58       echo 15
59       echo 16
60       echo 17
61       fc -l

-l オプションと一緒に引数を2つ指定した場合は1つ目の引数から2つ目の引数の間の履歴番号を持つ履歴が表示されます。

# 55番目から59番目のコマンド履歴が表示される
$ fc -l 55 59
55       echo 12
56       echo 13
57       echo 14
58       echo 15
59       echo 16

-l オプションの引数に数値以外が指定された場合は、コマンドの実行履歴を最近のものから前方一致で検索し見つかった履歴以降をすべて表示します。

$ fc -l 45
45       echo 00
46       echo 11
47       echo 21
48       echo 12
49       echo 22
50       fc -l -r 4
51       fc -l 46

$ fc -l "echo 1"
48       echo 12
49       echo 22
50       fc -l -r 4
51       fc -l 46
52       fc -l 42

$ fc -l "echo 11"
46       echo 11
47       echo 21
48       echo 12
49       echo 22
50       fc -l -r 4
51       fc -l 46
52       fc -l 42
53       fc -l "echo 1"

$ fc -l "echo 11" "echo 2"
46       echo 11
47       echo 21
48       echo 12
49       echo 22

$ fc -l "echo 11" "echo 21"
46       echo 11
47       echo 21

ちなみに fc コマンドに保存されるコマンドの実行履歴の数は HISTSIZE 環境変数の設定値に依存します。
もし HISTSIZE 環境変数が設定されていない場合は 128 コマンドまでが保存されます。

同様に保存されるコマンドの実行履歴が保存されるファイルは HISTFILE 環境変数の設定値に依存します。
設定されていない場合には ~/.bash_history ファイルに保存されます。

直前に実行したコマンドをエディタで編集し実行

アプリケーションをインストールする状況を想像してください。

$ apt install php-mysql -y

追加で php-mbstring をインストールしたいとします。

次のコマンドをタイプします。

$ apt instal php-mbstring -y

実行した結果、エラーとなります。
install のつづりが誤っていたためです。
コマンド入力は面倒な上にタイプミスの原因となります。

そんなときは fc を引数無しで実行します。

$ fc

デフォルトでは Vim エディタが起動し、最後に実行された apt install php-mysql -y が表示されています。
mysql の部分を msbstring に書き換え :wq コマンドで保存、終了します。
すると apt instal php-mbstring -y が実行されます。

軽微な内容なら「上矢印キー」を押して直前のコマンド履歴を起動した後に書き換えてもよいのですが、コマンドが複雑な場合は使い慣れたエディタの方が編集しやすいです。

ちなみに使われるエディタは次の順番で選定されます。

  1. FCEDIT 環境変数に設定されているコマンド
  2. EDITOR 環境変数に設定されているコマンド
  3. vi コマンド

他コマンドでもよく使われる EDITOR 環境変数に好きなエディタコマンドを設定しておくのがよいでしょう。

過去に実行した任意のコマンドをエディタで編集し実行

fc コマンドをオプション無しで実行すると直前実行されたコマンドを編集対象とします。
更に前の履歴を編集対象としたい場合には引数に履歴番号をしてしいます。

$ fc -l
1        apt install vim -y
2        env
3        apt install php-mysql -y
4        apt install php-mbstring -y
5        fc -l
6        fc --help

$ fc 3

この結果、 Vim には apt install php-mysql -y が表示されます。
あとは実行したい希望のコマンドに編集した後、 :wq でエディタを終了します。

過去に実行した複数のコマンドをひとまとめに実行

更に変わった使い方について紹介します。
fc コマンドの対象は 1 つのコマンドだけではなく、過去に実行した複数のコマンドを選択できます。

まずは履歴を表示します。

$ fc -l
1        apt install vim -y
2        env
3        apt install php-mysql -y
4        apt install php-mbstring -y
5        fc -l
6        fc --help

ここで過去に実行した apt の 3 つの履歴を再利用したいとします。
その場合、対象としたい履歴の開始番号と終了番号を指定します。

ここでは履歴 134 を選択したいので、番号の最小値 1 と最大値 4 を引数として渡します。

$ fc 1 4

エディタには次の内容が表示されるはずです。

apt install vim -y
env
apt install php-mysql -y
apt install php-mbstring -y

不要な 2 行目の env は削除して :wq でエディタを保存、終了すれば、3 つのコマンドが実行できます。
もちろん適切な内容に追加編集しても構いません。

直前に実行したコマンドを編集せずに実行

過去に実行したコマンドをそのまま実行できます。

1        apt install vim -y
2        env
3        apt install php-mysql -y
4        apt install php-mbstring -y
5        fc -l
6        fc --help
7        fc -l
8        apt install php-mysql -y
9        fc -l
10       apt install vim -y
11       fc --help
12       fc -l
13       apt install vim -y
14       apt install php-mysql -y
15       apt install php-mbstring -y

もう一度ヘルプを引きたいということで、 11 番の fc --help を実行してみます。

$ fc -s 11
fc --help
fc: fc [-e ename] [-lnr] [first] [last] or fc -s [pat=rep] [command]
    Display or execute commands from the history list.
...

しかし、これについては Bash や Zsh のコマンド履歴をあいまい検索できるツールが提供されているのでそちらを利用するのが良いでしょう。
僕の他ツールを利用しています。

ひとこと

じゃあ fc コマンドを使うかというと、現在表示中のコマンドをエディタで開くためのショートカットキーも提供されているので僕はそちらを利用することが多いですね。

!! コマンドを使うことも多いですしね。

リモートサーバー上での操作時に生きてきそうです。

2023-12-31Bash