個人的に利用しているBashの機能紹介 

この記事は[MicroAd Advent Calendar 2021](https://qiita.com/advent-calendar/2021/microad)の13日目の記事です。

# 概要

この記事では，Bashで利用できるシェルの機能について，個人的に最低限必要に感じるものについて紹介します．
必要かどうかや，便利かどうかは筆者の主観的ですので，参考までにしていただければ幸いです．


## コマンド履歴を使いやすくする

シェルの実行履歴に関する設定は以下のようなものがあります．

- メモリに保存する履歴数(`HISTSIZE`)
- ファイルに保存する履歴数(`HISTFILESIZE`)
- 履歴のフォーマット(`HISTTIMEFORMAT`)
- 履歴に残さないコマンド(`HISTIGNORE`)

これらは，以下のように環境変数で設定可能です．

```
export HISTSIZE=10000
export HISTFILESIZE=10000
export HISTTIMEFORMAT="%Y/%m/%d %H:%M:%S "
export HISTIGNORE=$'&:ls:ll:la:ps:top:df:du'
```

`HISTIGNORE`は履歴から除外したいものを`:`区切りで書きます．
`&`は重複するコマンドを示します．他は表示のみでファイルに変更を加えないコマンドを加えてています．


## 履歴を保存するタイミングの変更する

環境変数`PROMPT_COMMAND`を指定することで，新しいプロンプトが表示される前に特定のコマンドを実行することができます．
以下のように設定することで，コマンド実行の度に履歴を残すことが可能です．
この設定で，複数ターミナルでの作業時に片方からもう片方の履歴を利用することができ，ターミナルの異常終了で履歴が残らないことの防止にもなります．

```
export PROMPT_COMMAND="history -a; history -c; history -r"
shopt -u histappend
```

2022.6.3 オプションの指定をタイポしていたので更新しました．
`export PROMPT_COMMAND="history -a; history -r; history -r"` でなく，
`export PROMPT_COMMAND="history -a; history -c; history -r"` です．

## 確認系のオプションをデフォルトにする

削除の確認(`-i`)や実行内容の確認(`-v`)の設定です．
間違えるとファイルの中身が消えるので念のために入れています．

```
alias rm='rm -iv'
alias cp='cp -iv'
alias mv='mv -iv'
alias ln='ln -iv'
```

## ctrl+w でスラッシュ区切りで削除できるようにする

シェル環境では，Ctrlキー+wキーで単語単位の削除が可能です．
しかし，単語はスペース区切りで認識されるため，ファイルのパスのようにスラッシュ区切りの文字列は全て削除されます．

そこで以下の設定を.bashrcなどで設定します．

```
stty werase undef
bind '"\C-w": unix-filename-rubout'
```

これにより，例えば`/etc/nginx/nginx.conf`と入力した状態で，Ctrl+wを押すと`/etc/nginx/`になります．

ちなみにzshの場合は，単語で使われる文字を環境変数`WORDCHARS`で指定することができるため，
この変数を自分で`/`を含まず定義することで実現できます．

```
WORDCHARS='*?_-.[]~=&;!#$%^(){}<>'
```

## sudo でもエイリアスを使う

ユーザの設定で追加したエイリアスは，sudoコマンド実行時には展開されないため使うことができません．
`sudo <半角スペース>`をエイリアス設定することで回避することができます．
これで`alias ls=ls -l`など設定している状態で`sudo ll`のように利用できます．

```
alias sudo='sudo '
```

これはBashの仕様として，エイリアスの最後がスペースであれば，次のコマンドもエイリアスかどうか確認されるようになっているためです．


## Gitコマンドのエイリアス

これはシェルのエイリアスでなくGitコマンドのエイリアスで本筋とは異なりますが，ついでに書きます．

Gitのコンフィグファイルへの記述，または`git config`コマンドによる設定が可能です．
設定の影響範囲は，システム(`/etc/gitconfig`)，ユーザ(`~/.gitconfig`)に分かれており，configコマンドの`--global`の否で決まります．

例えば，以下のようなコマンドで設定すると`git s`と入力で`git status`と同じになります．

```
git config --global alias.s status
```

筆者は以下のような設定を入れています．
タイプ数が多いものや，オプションが多いものは入れておくと便利になるかと思います．

```
git config --global alias.s status
git config --global alias.st status -uno
git config --global alias.a add
git config --global alias.b branch
git config --global alias.cm commit
git config --global alias.b branch -a
git config --global alias.c checkout
git config --global alias.dn diff --name-only
git config --global alias.dw diff --word-diff
git config --global alias.g "log --graph --date=short --decorate=short --pretty=format:'%Cgreen%h %Creset%cd %Cblue%cn %Cred%d %Creset%s'"
git config --global alias.l "log --graph --all --decorate"
```

# まとめ

本稿では，シェルの機能で個人的に便利だと感じるものを紹介しました．
設定内容によっては好みに次第なものもあるので一概に何がいいとは言えませんが，作業効率を上げるためのきっかけになれれば幸いです．

本当は[前回書いた記事](https://qiita.com/bosq/items/9ed0b6a3d8ea71d3d21a)のような構築系の内容をKafkaで書こうと考えていたのですが，前回思ったより時間がかかってしまったため変更しました．
また，以前から業務用のシェル環境を整理しようと思いつつ時間を取っていなかったので，良い機会になりました．

> もし8時間、木を切る時間を与えられたら、そのうち6時間を私は斧を研ぐのに使うだろう。

このような言葉もあるように，まずは作業効率を上げるための環境作りを大事にしていきたいです．