`bash` でディレクトを移動した時と、コマンドが空の状態で Enter を押したときに `ls` と `git status` を表示する (よく使うコマンド操作の簡略化・自動化)
目次
目的
コマンド履歴を確認したところ、いつも同じようなコマンドを実行していることが分かった。
操作の簡略化・自動化できる要素が多分にあったため、その対応を行う。
$ cat /etc/debian_version stretch/sid $ uname -a Linux calc0 4.4.0-59-generic #80-Ubuntu SMP Fri Jan 6 17:47:47 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux $ cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=16.04 DISTRIB_CODENAME=xenial DISTRIB_DESCRIPTION="Ubuntu 16.04.1 LTS"
コマンド履歴の確認
コマンド履歴の達人を目指してみる - ザリガニが見ていた…。のコマンドを参考にさせていただきました。
$ history|sed -e 's/sudo //g'|awk '{ print $2 }'|sort|uniq -c|sort -r|head 1181 ll 918 vi 619 cd 534 git 245 apt 226 l 211 systemctl 165 journalctl 133 rm 129 cat
方法
できるだけキー入力を省略できるような仕組みと、定期実行でコマンド自動化(cron等)を行う。
bash
でコマンドが空の状態で Enter を押したときに ls
と git status
を表示する
下記の仕組みを用いれば、ls
とgit
の入力を減らすことができると考えた。
コマンドが空であることの判定は、~/.bash_history
の行数の増加をチェックして用いることにした。
当該コードについては次のトピックが関連するので、次のセクションのコードに併記します。
ディレクトリを移動したら自動で ls
と git status
を表示する
下記を参照しました。
本件は PROMPT_COMMAND
を用いることで複数のコマンド実行を実現しており、それを dispatch
にて処理するために下記を参照しました。
そして、前述の内容のコードを合わせた下記のコードを.bashrc
に追記します。
# Git repository check function check_git { if [ "$(git rev-parse --is-inside-work-tree 2> /dev/null)" = 'true' ]; then echo -e "\e[0;33m--- git status ---\e[0m" git status -sb fi } # cd -> cd + ls function autols { if [ "${AUTOLS_DIR:-$PWD}" != "$PWD" ]; then ls -ACF check_git fi AUTOLS_DIR="${PWD}" } export PROMPT_COMMAND_AUTOLS="autols" # Enter -> ls + git status export HISTCONTROL=ignorespace COUNT=$(wc -l < ~/.bash_history) function lsgit { COUNT_TMP=$(wc -l < ~/.bash_history) if [ "$COUNT" != "$COUNT_TMP" ]; then COUNT="$COUNT_TMP" return 0 fi ls -ACF check_git } export PROMPT_COMMAND_LSGIT="lsgit" dispatch () { export EXIT_STATUS="$?" local f # shellcheck disable=SC2153 for f in ${!PROMPT_COMMAND_*}; do eval "${!f}" done unset f } export PROMPT_COMMAND="dispatch"
挙動
まず history
の挙動について下記を一読ください。
・先頭がスペースであるコマンドを履歴に残さない方法 > ※はてなブックマークでの補足コメント、有難う御座いました。
1 > export HISTCONTROL=ignorespace
・先頭がスペースであるコマンドを履歴に残さない+重複コマンドを記録しない方法1 > export HISTCONTROL=ignoreboth
Linuxでコマンド履歴を残さない方法 | 十円玉という名のブログ
~/.bashrc
に記載があるのですが、デフォルトではHISTCONTROL=ignoreboth
の設定です。
今回コード中でexport HISTCONTROL=ignorespace
を指定しており、その点をふまえて本件の挙動を確認してみます。
トップに置いてあるスクリーンショットをここで再掲しますので、合わせて挙動を確認してみてください。
cd ~/.github/
を実行する(cd
入力がないが、省略する設定を行っている。後述。)- ディレクトリを移動したら自動で
ls
とgit status
を表示する(git
リポジトリではないのでstatus表示はなし) cd dotfiles
を実行する- ディレクトリを移動したら自動で
ls
とgit status
を表示する w
コマンドの実行w
コマンドの結果表示- コマンドが空の状態で Enter を押す
~/.bash_history
の行数が増えなかったため、ls
とgit status
を表示するcd .git
を実行する- ディレクトリを移動したら自動で
ls
とgit status
を表示する(git
リポジトリではないのでstatus表示はなし) cd ..
の実行- ディレクトリを移動したら自動で
ls
とgit status
を表示する cd ..
の実行- ディレクトリを移動したら自動で
ls
とgit status
を表示する(注意:HISTCONTROL=ignoreboth
の条件では、同じコマンドを続けて実行した際は~/.bash_history
の行数が増えないため、ls
とgit status
が表示されるという動きになってしまい、ここでは"ディレクトリを移動したら"もTRUEなので2回ls
とgit status
が表示されてしまいます。)
※どこのディレクトリでもgit
リポジトリか確認してgit status
を表示するという手もありますが、リポジトリ内でコマンド実行のたびにgit status
が表示されるのは可読性が悪くなると思い、上記のような挙動をコーディングしました。
bash
でのcd
入力の省略
~/.bashrc
にshopt -s autocd
を追記すると、ディレクトリ名のみが入力された際にcd
が自動追記されます。
apt
の定期実行
下記2サイトを参考にしました。
3 unattended-upgradesパッケージ
自動アップグレードを実行するパッケージです。
デフォルトだとセキュリティアップデートのみをアップグレードする設定になっています。
アップデート後にシステム再起動が必要な場合に再起動させることも設定できます。
サーバ運用している場合はアップグレード作業が不要になるので便利なツールです。
Ubuntu 16.04: 自動アップデート / アップグレードの設定をする - Narrow Escape
自分の環境ではすでにインストールされていることが確認できたので、/etc/apt/apt.conf.d/20auto-upgrades
の内容を確認して、足りない内容を追記しました。(自動実行自体は過去に"ソフトウェアとアップデート"で設定していたのか、インストール時に設定していたのかできていたよう…)
$ sudo apt -y install unattended-upgrades パッケージリストを読み込んでいます... 完了 依存関係ツリーを作成しています 状態情報を読み取っています... 完了 unattended-upgrades はすでに最新バージョン (0.90ubuntu0.3) です。 アップグレード: 0 個、新規インストール: 0 個、削除: 0 個、保留: 0 個。 $ echo 'APT::Periodic::AutocleanInterval "1";' | sudo tee -a /etc/apt/apt.conf.d/20auto-upgrades APT::Periodic::AutocleanInterval "1"; $ echo 'APT::Periodic::Download-Upgradeable-Packages "1";' | sudo tee -a /etc/apt/apt.conf.d/20auto-upgrades APT::Periodic::Download-Upgradeable-Packages "1";
(2017/1/23 追記)
/etc/apt.conf.d/50unattended-upgrades
に対して、アップグレード対象をセキュリティだけでなく通常のアップデートも含めるためのコメントインと、更に自分はPPAから外部パッケージのNeovim
をインストールしていたので下記を参照にしてレポジトリの追加を行った。
$ head /var/lib/apt/lists/ppa.launchpad.net_neovim-ppa_unstable_ubuntu_dists_xenial_InRelease -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 Origin: LP-PPA-neovim-ppa-unstable Label: Neovim Unstable Suite: xenial Version: 16.04 Codename: xenial Date: Sun, 22 Jan 2017 20:50:44 UTC Architectures: amd64 arm64 armhf i386 powerpc ppc64el s390x $ $ head /etc/apt.conf.d/50unattended-upgrades // Automatically upgrade packages from these (origin:archive) pairs Unattended-Upgrade::Allowed-Origins { "${distro_id}:${distro_codename}"; "${distro_id}:${distro_codename}-security"; "${distro_id}:${distro_codename}-updates"; // "${distro_id}:${distro_codename}-proposed"; // "${distro_id}:${distro_codename}-backports"; "LP-PPA-neovim-ppa-unstable:xenial"; }; $ sudo mv /etc/cron.daily/apt-compat /etc/cron.daily/.apt-compat
cron
によるコマンドの自動実行
Saba noteを参考に、いつもapt
と一緒に実行していた下記のコマンドを一日一回は実行するように設定しました。
$ crontab -l # min hour day mth wday user command 10 23 * * * ito trash-empty 30 >/dev/null 2>&1 20 23 * * * ito nvim -c "call dein#update()|q" >/dev/null 2>&1
本環境でのファイル削除は、rm
の代わりにtrash
コマンドを用いています。(CLI削除の場合もゴミ箱に投入され、削除して30日経過したファイルをゴミ箱からも削除する設定にしています。)
Neovim プラグインのアップデートも一日一回できるようになりました。(プラグインアップデート関数の実行を引数として与え、実行後にNeovimを終了しています。)
暗黒美夢王(deo developer)(@ShougoMatsu)さん、いつもありがとうございます!!
まとめ
目的は達成できた。
これでコマンド履歴の確認のトップ10のうち、下記のコマンドの入力回数が減ることが期待できます。
- ll
- cd
- git
- apt
- l
余談
次は自動ログ監視の仕組みを用いてjournalctl
の入力回数を減らしたいですね。
しかしながら、journalctl
とsystemctl
の入力回数が多いのは、下記の開発のためですね。懐かしい。
以上