普段何気なく利用している/tmp
と/var/tmp
。
意識して使い分けてる方も分けてない方もいらっしゃるかと思います。
Linuxのファイルシステムとしての存在意義や、一時フォルダとしての機能を改めて意識すると
非常に便利な存在です。
/tmpと/var/tmpの違い
「/tmpと/var/tmpの違いについて述べよ」・・・インフラエンジニアの入社試験の問題に出てきそうですね。 さて単純な解答ですが、システム的なことを言えば以下あたりです。(RHEL)
/tmp | /var/tmp |
---|---|
再起動時にファイルが削除される | 再起動しても消えない |
10日間アクセスが無い場合削除 | 30日間アクセスが無い場合削除 |
どちらもディレクトリ配下はtmpwatchコマンドにより監視されファイルの削除が組み込まれています。
$ cat /etc/cron.daily/tmpwatch
#! /bin/sh
flags=-umc
/usr/sbin/tmpwatch "$flags" -x /tmp/.X11-unix -x /tmp/.XIM-unix \
-x /tmp/.font-unix -x /tmp/.ICE-unix -x /tmp/.Test-unix \
-X '/tmp/hsperfdata_*' 10d /tmp
/usr/sbin/tmpwatch "$flags" 30d /var/tmp
for d in /var/{cache/man,catman}/{cat?,X11R6/cat?,local/cat?}; do
if [ -d "$d" ]; then
/usr/sbin/tmpwatch "$flags" -f 30d "$d"
fi
done
個人的には/tmp
は「見返すことのない、ファイル名も適当で良いような一時ファイル」、
/var/tmp
は「また参照するかもしれない、ファイル名がある一時ファイル(sqlのdumpなど)」
として使い分けています。
ある程度ルールを持って配置しておくと後々参照する時に楽です。
ファイルを取得する時にあえて一時ディレクトリを経由させる
リモートマシンにSSHにてログインしていて、 そこで操作しているファイルを他サーバの任意のワーキングディレクトリにコピーしたいとします。
$ ssh [email protected]
$ cd /etc/httpd/
$ ls httpd.conf #このファイルを別サーバの特定のディレクトリにコピーしたい
こういった状況下の時にどのようにすれば楽でしょうか?
直接転送したいとすれば、pwd
をしたのち、SSH用のIPアドレスもメモしてフルパスを入力します。
$ scp httpd.conf [email protected]:/root/project/httpd-conf-update/
ただしこの手法はやや面倒です。パスのコピーのために画面の行き来が必要ですし、 なにせ、もし何か入力ミスがあると、その場所を探すのが大変です。
この場合、まず何も考えずにとにかく/tmp
へ転送をさせます。
$ scp httpd.conf [email protected]:/tmp
その後に転送先のサーバでmv
をさせます。
$ cd /root/project/httpd-conf-update/
$
$ mv /tmp/h[tab]
$ mv /tmp/http.conf ./
ログインしているサーバであれば、tabキーによるパスのサジェストももちろん利用できるので、
スムーズにファイルパスを取得することが出来ます。
「/tmp
ディレクトリは消えても良いファイルを置いている」という前提を立てていれば、
心置きなく転送することが出来ます。
複数サーバの操作の場合、2画面以上開いて作業されている方も多いはずです。
そういった場合、とりあえず/tmp
にコピーするというルールさえあれば、
たった/tmp
というたった固定の4文字を打つだけで、面倒なディレクトリパス問題を
気にしないで済みます。
ローカルMacにもコピーしたい場合のお勧め手法
tmux等のsend-keysのエイリアスを予め用意し、
固定値のPATHにコピーしてしまう仕組みを作ると簡単です。
ここでのお勧めは/tmp
ではなく、ユーザのホームをリンク先にしてしまうことです。
~/.tmux.conf
bind R send-keys '[email protected]:/Users/Ricky/' C-m
$ scp httpd.conf [C-b R]
$
$ scp httpd.conf [email protected]:/Users/Ricky/
ユーザのホームディレクトリ/Users/[Username]
は~/
でも同値となりますので、
$ mv ~/httpd.conf .
もっと少ない文字列でとて簡単に手元にデータを持ってくることが可能です。
Macで少し生産性の上がるBashエイリアス集でも解説した、現在開いているFinderのPATHに移動するcdf
コマンドと組み合わせれば、
開いているFinderディレクトリに簡単にリモートファイルを取得することが出来ます。
$ cdf
/Users/Ricky/Projects/01_Main/20140910_httpd_conf_update
$ mv ~/ht [tab]
$ mv ~/httpd.conf . #データ取得完了
シェルスクリプトとしての/tmpの存在意義
シェルスクリプトでも活用法が沢山あります。
あまり有名ではないですが、
Linuxでは実は既にデフォルトでmktemp
というテンポラリファイルPATHをランダムで作ってくれるとても便利な
コマンドがあります。
$ mktemp
/tmp/tmp.PZ5TDqVte4
何か複数にまたがったファイルを集計したい場合、mktempを経由すれば簡単です。 任意のサーバにあるApacheのアクセスログのユニークIP数を集計してみます。
main () {
tmp=$(mktemp)
for server in 192.168.33.201 192.168.33.202
do
scp $server:/var/log/httpd/access_log.20140920 /tmp/$server
cat /tmp/$server >>$tmp
done
#複数サーバのapacheログのuniq ip数の集計
awk '{ print $1 }' $tmp | sort -u | wc -l
}
main $@
いったんファイルを取ってきて、それをcat
コマンドで結合、
結合ファイルを集計するという流れです。
「集計してほしい」と依頼が到着した時に、サクッとtmpファイルにコピー、
内容を結合したものを集計して出せるとなかなか素敵です。
main () {
tmp=$(mktemp)
sort import_mysql_text.tsv >$tmp
}
main $@
MySQLなどの場合は予めsortされたファイルをインポートすると高速なことは有名です。 「一瞬ソートする」というアクションもmktempコマンドさえあれば心置きなく出来ます。
BashのRsync用のエイリアスとして用意する
以下のグローバルエイリアスを~/.bashrc
などに設定します。
alias -g R="| rsync -av --files-from=- . /tmp/"
「Gitファイルで差分のものだけディレクトリ構成を残して取得したい」などのリクエストの時に便利です。
$ git diff --name-only HEAD~~~ R #Rがグローバルエイリアスでパイプ&Rsyncしてくれる
上記を書き込むだけでディレクトリ構成をキープして、/tmp
以下に簡単にコピー出来ます。
あとはこの記事で記載の通り、/tmpからTabによるPathのサジェストを利用して手元にコピーです。
mv /tmp/co [tab]
mv /tmp/copied_file .
最後に
たかがtmpディレクトリですが、活用出来ればなかなか強力です。 もっと便利な活用方法等ありましたら是非共有お願いします。