`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
の入力回数が多いのは、下記の開発のためですね。懐かしい。
以上
"SysVinit" 起動の自作 deb パッケージを "systemd" 対応させる
目次
目的
以前作成した deb パッケージが "SysVinit" 起動だったため、自分の環境が "Ubuntu16.04" になったこともあり "systemd" 対応を行った。
方法
"debhelper" の "systemd" 対応
下記記事の通り、debian/control
、debian/rules
に追記を行いました。
systemd対応¶
systemdの場合は、debhelperのadd onとして、dh-systemdが用意されています。 ですので、まず、 debian/control のBuild-Dependsに、dh-systemdを追記します。
Build-Depends: debhelper (>= 8.0.0), (snip), dh-systemd (>= 1.5), (snip)
次に、 debian/rules の%ターゲットのdhコマンドのオプションとして、systemdを追記します。%:
dh $@ --with quilt,systemd
systemd用の設定ファイルは、upstartと同様テンプレートは用意されていません。debian/<パッケージ名>.serviceとして用意します。debian/yrmcds.service として作成します。上記のみで、あとはdh-systemdが良きように設定してくれるのですが、これだけではpurge(apt-get purge)の時に残骸が残ります。 ですので、 postrm で下記のファイルを削除します。
/etc/systemd/system/yrmcds.service
/etc/systemd/system/multi-user.target.wants/yrmcds.service
/var/lib/systemd/deb-systemd-helper-enabled/yrmcds.service.dsh-also
/var/lib/systemd/deb-systemd-helper-enabled/multi-user.target.wants/yrmcds.service
/var/lib/systemd/deb-systemd-helper-masked/yrmcds.service
How to create a Debian package of support to sysvinit, upstart, systemd — ペンギンと愉快な機械の日々
deb パッケージの Ubuntu16.04(xenial) 対応
下記に記載がありますとおり、debian/changelog
の対象ディストリビューション記載を変更します。
That format is a series of entries like this:
package (version) distribution(s); urgency=urgency [optional blank line(s), stripped] * change details more change details [blank line(s), included in output of dpkg-parsechangelog] * even more change details [optional blank line(s), stripped] -- maintainer name <email address>[two spaces] date
package and version are the source package name and version number.
distribution(s) lists the distributions where this version should be installed when it is uploaded - it is copied to the Distribution field in the .changes file. See Distribution, Section 5.6.14.
Debian Policy Manual - Source packages
実際は dch -v 1.5-2ppa
などを実行して debian/changelog
を編集します。
下記コードでは、"1.5-2ppa" のバージョンから "xenial" に変更されていることがご覧いただけるかと思います。
likana (1.5-2ppa) xenial; urgency=low * Set up a systemd. -- ito <maijou2501@gmail.com> Thu, 15 Sep 2016 23:43:45 +0900 likana (1.4-1ppa) precise; urgency=low * Fix, typo and binary path. -- ito <maijou2501@gmail.com> Fri, 16 Sep 2016 23:41:21 +0900
これで "PPA" にてバイナリが作成される際のディストリビューション指定が完了しました。
debian/package.service
の作成
"systemd" の "Unit" を書く前にそもそも "systemd" の仕組みが分かっていなかったので、先ほどの記事や下記の記事で理解を深めた。
自分の場合でも、/etc/init.d/package
の内容をもとに、"service" の "Unit" を作成した。
"systemd" での設定ファイルについて
設定ファイルは同じ /etc/default/package
を用いて良いようだ。
SystemdForUpstartUsers - Ubuntu Wiki
Existing sysvinit style scripts read configuration in the form of variable assignments from a file under /etc/default. A policy decision is needed on whether systemd units will do the same.
しかし下記の記事内容のとおりで変数の扱いが違うようで、/etc/default/package
の中で変数の代入に変数を用いないようにした。
systemd の Environment / EnvironmentFile では変数展開できません - Qiita
"systemd" での /etc/default/package
への配置を Makefile
にて対応
"SysVinit" の場合、debian/package.default
を利用することで、/etc/default/package
へ配置できていたが, 自分の設定が足りないせいなのか "systemd" を用いた場合に配置がうまくいかなかった。
正しい対応ではないかもしれないが、Makefile
の "install" ルールにて対応した。
-snip- install: -snip- test -e ${DESTDIR}/etc/default && install -m 644 -g root -o root debian/${NAME}.default ${DESTDIR}/etc/default/${NAME} -snip-
debian/postrm
への追記
先ほどの記事を参考に、削除すべきファイルを設定した。
自分の場合は debian/package.udev
を利用しているので、/etc/udev/rules.d/*package.rules
を削除する設定を追加した。
"systemd" の "service" の実行を "input" グループで行う
自作のサービスでは /dev/input/event*
をオープンするもので、"systemd" では "service" のグループを "input" に設定しないといけないようであった。
$ ls -l /dev/input/ 合計 0 drwxr-xr-x 2 root root 100 10月 30 23:19 by-id drwxr-xr-x 2 root root 100 10月 30 23:19 by-path crw-rw---- 1 root input 13, 64 10月 30 23:19 event0 crw-rw---- 1 root input 13, 65 10月 30 23:19 event1 crw-rw---- 1 root input 13, 66 10月 30 23:19 event2 crw-rw---- 1 root input 13, 67 10月 30 23:19 event3 crw-rw---- 1 root input 13, 68 10月 30 23:19 event4 crw-rw---- 1 root input 13, 69 10月 30 23:19 event5 crw-rw---- 1 root input 13, 70 10月 30 23:19 event6 crw-rw---- 1 root input 13, 71 10月 30 23:19 event7 crw-rw---- 1 root input 13, 72 10月 30 23:19 event8 crw-rw---- 1 root input 13, 73 10月 30 23:19 event9 crw-rw-r-- 1 root input 13, 0 10月 30 23:19 js0 crw-rw---- 1 root input 13, 63 10月 30 23:19 mice crw-rw---- 1 root input 13, 32 10月 30 23:19 mouse0
まとめ
目的のとおり、以前作成した deb パッケージ(likana)の "systemd" 対応を行うことができた。
※ "PPA" での公開 " likana : kyohei ito "