Gitの対象から外したいけど、ファイル自体は残しておきたい

問題

  • Gitでバージョン管理していたファイルを残したまま追跡の対象外にしたい。
  • 既に管理対象になっているファイルは、後から.gitignoreにファイル名を追加しても変更の追跡が継続される。

対応方法

一旦ファイルを削除したというcommitを作成して、再度加えることで管理の対象外だと認識させる。

$ git rm --cached want-to-ignore-file
# --cachedオプションがあると、ファイル自体は削除されない。

# 追跡を止めたいファイルを.gitignoreに追加する。
$ EDIT .gitignore

# 必要なら.gitignoreをcommitに含める。
$ git add .gitignore

$ git commit

$ git add want-to-ignore-file

参照

USBにドライブが接続されたら自動的にバックアップを作成したい

目的

USB接続のディスクドライブにバックアップを作成するシェルスクリプトbackup.shがあります。USBにディスクドライブが接続されたら、このスクリプトを自動的に実行するようにしてバックアップの手間を減らしたい。

環境

OS
Ubuntu 16.04

解決策

方針

Ubuntu 16.04を含む最近のLinuxは、デバイスの管理にudevを使用しています。そのため適当なruleファイルを作成すると、デバイスが接続されたり取り外された時に決まったプログラムを実行させることができます。

そこでudevにドライブがUSBに接続されたらバックアップ用のシェルスクリプトbackup.shを実行するルールを作成します。

ただしudevのルールから起動できるプログラムは、短時間で終了する必要があります。バックアップなど終了までに時間がかかるプログラムを実行させようとすると、途中で強制的に終了させられてしまいます1

この制限を回避するために、バックアプをsystemdのサービスとして、udevからはそのサービスを開始するようにします。

systemdサービス

まずバックアップを作成するサービスを定義します。

/etc/systemd/system/backup.service

[Unit]
Description=Backup to Removable USB Drive

[Service]
Type=simple
ExecStart=/root/bin/backup.sh

サービスを定義したら次のコマンドでsystemdに登録します。

# systemctl daemon-reload
# systemctl status backup
* backup.service
   Loaded: not-found (Reason: No such file or directory)
   Active: inactive (dead)

なおsystemdから起動されたプログラムの標準出力は、syslogに記録されると同時にsystemctl status SERVICE_NAMEで確認できます。

udevルール

サービスを登録したら、そのサービスを起動するルールを作成します。

/etc/udev/rules.d/91-backup.rules

ACTION=="add",ENV{ID_BUS}=="ata",ENV{ID_PART_ENTRY_UUID}=="xxxx-xxxx-xxxx-xxxx",RUN+="/bin/systemctl --no-block start backup.service"

デバイスを識別するENVには、udevが認識している値を設定します。認識している値は、udevadm info --name=XXXコマンドで取得できます。

ルールを作成したら、次のコマンドでudevにルールを登録します。

# udevadm control --reload

これでxxxx-xxxx-xxxx-xxxxというUUIDを持つディスクパーティションがataに接続されたらbackup.serviceが起動されます。

参照と脚注

  1. 終了までに時間がかかるプログラムをudevから起動すると途中で強制終了させられる問題を回避するためにバックグラウンドで処理させるようにしても終了させられてしまいます。この問題は、setsidコマンドでセッションIDを変えて、自分がセッションリーダーとなれば終了させられないという記述を見たことがあります。