- Contents -
Shellで一時ディレクトリを利用する
シェルスクリプトで一時ディレクトリを利用したい場合は、よくあります。
そんなときに使えるテンプレをここに記載しておきます。
一時ディレクトリ利用のテンプレ
tempdir_sample.sh
#!/bin/bash
set -ux
# 一時ディレクトリを作成 (Pathを変数に代入しておく)
temp_dir=$(mktemp -d)
# スクリプト終了時に一時ディレクトリを削除
trap 'rm -rf $temp_dir' EXIT
# TODO: ここで一時ディレクトリでやりたい処理を
touch $temp_dir/hoge
touch $temp_dir/piyo
touch $temp_dir/foo
ls $temp_dir
echo "done"
mktempコマンドで一時ディレクトリを作成しています。
作成したディレクトリは、スクリプト終了時に削除してほしい場合は、
trapコマンドを利用します。
実行したときの結果は下記のとおり。
set -x
としているので、実行コマンドは表示しています。
$ bash tempdir_sample.sh
++ mktemp -d
+ temp_dir=/var/folders/d9/h72gyc550rg_tw97v9c72hl80000gn/T/tmp.iEIexH9M
+ trap 'rm -rf $temp_dir' EXIT
+ touch /var/folders/d9/h72gyc550rg_tw97v9c72hl80000gn/T/tmp.iEIexH9M/hoge
+ touch /var/folders/d9/h72gyc550rg_tw97v9c72hl80000gn/T/tmp.iEIexH9M/piyo
+ touch /var/folders/d9/h72gyc550rg_tw97v9c72hl80000gn/T/tmp.iEIexH9M/foo
+ ls /var/folders/d9/h72gyc550rg_tw97v9c72hl80000gn/T/tmp.iEIexH9M
foo hoge piyo
+ echo done
done
+ rm -rf /var/folders/d9/h72gyc550rg_tw97v9c72hl80000gn/T/tmp.iEIexH9M
一時ディレクトリが作成され、
スクリプト終了時にはディレクトリが削除できているのがわかります。
サブシェルを利用したテンプレ
サブシェルを利用すると、
特定の処理だけ一時ディレクトリで作業させる事もできます。
tempdir_with_subshell_sample.sh
#!/bin/bash
set -ux
# 括弧を使うとサブシェルになる
(
echo "sub-shell start"
# 一時ディレクトリ作成
temp_dir=$(mktemp -d)
# サブシェル終了時に発動する
trap 'rm -rf $temp_dir' EXIT
# サブシェル内のディレクトリ移動は親シェルに影響しない
cd $temp_dir
# TODO: ここで一時ディレクトリ内でやりたい処理を
touch hoge
touch piyo
touch foo
ls
echo "sub-shell done"
)
echo "done"
cd
する場合、
スクリプト実行したシェル自体のカレンドディレクトリも変わってしまう。
サブシェル内でcd
するのであれば、
親シェルに影響を与えないのでオススメです。
実行結果がこちら↓
$ bash tempdir_with_subshell_sample.sh
+ echo 'sub-shell start'
sub-shell start
++ mktemp -d
+ temp_dir=/var/folders/d9/h72gyc550rg_tw97v9c72hl80000gn/T/tmp.NsxyR6RE
+ trap 'rm -rf $temp_dir' EXIT
+ cd /var/folders/d9/h72gyc550rg_tw97v9c72hl80000gn/T/tmp.NsxyR6RE
+ touch hoge
+ touch piyo
+ touch foo
+ ls
foo hoge piyo
+ echo 'sub-shell done'
sub-shell done
++ rm -rf /var/folders/d9/h72gyc550rg_tw97v9c72hl80000gn/T/tmp.NsxyR6RE
+ echo done
done
trap処理も、サブシェルで実行しているので
サブシェル終了時に一時ディレクトリ削除がおこなわれているのがわかります。
mktempコマンドについて
mktempコマンドは、
TMPDIR
環境変数をみて一時ファイルを作成するコマンド。
$ echo $TMPDIR
/var/folders/d9/h72gyc550rg_tw97v9c72hl80000gn/T
Macの場合だと、↑こんな感じになってるはず。
一時ファイルの作成
普通につかうと、
一時ディレクトリではなくファイルが作成されます。
作成されるファイルはランダムでユニークな名称で作成されます。
$ mktemp
/var/folders/d9/h72gyc550rg_tw97v9c72hl80000gn/T/tmp.IdOVCZul
$ ls -lha /var/folders/d9/h72gyc550rg_tw97v9c72hl80000gn/T/tmp.IdOVCZul
-rw------- 1 tyab staff 0B 3 7 12:58 /var/folders/d9/h72gyc550rg_tw97v9c72hl80000gn/T/tmp.IdOVCZul
mktempコマンドは、作成した一時ファイルのPATHを出力します。
ShellScriptでは、この出力をShell変数に代入して利用する。
-t
オプションでプレフィックスを指定することもできます。
$ mktemp -t hoge
/var/folders/d9/h72gyc550rg_tw97v9c72hl80000gn/T/hoge.0XLPF25S
一時ディレクトリの作成
ファイルではなく、一時ディレクトリを作成したい場合は、
-d
オプションを使います。
$ mktemp -d
/var/folders/d9/h72gyc550rg_tw97v9c72hl80000gn/T/tmp.XokR90r0
$ ls -lha $TMPDIR
drwx------ 2 tyab staff 68B 3 7 13:02 tmp.XokR90r0
同じように、$TMPDIR
配下にユニークな名称でディレクトリが作成され、
作成されたディレクトリのPATHが出力されます。
コマンドのオプション
-d
と -t
オプションくらいを知っていれば問題ないですが、
コマンドのマニュアルは一度みておくと良いです。
$ man mktemp
NAME
mktemp -- make temporary file name (unique)
SYNOPSIS
mktemp [-d] [-q] [-t prefix] [-u] template ...
mktemp [-d] [-q] [-u] -t prefix
OPTIONS
The available options are as follows:
-d Make a directory instead of a file.
-q Fail silently if an error occurs. This is useful if a script does not want
error output to go to standard error.
-t prefix
Generate a template (using the supplied prefix and TMPDIR if set) to create
a filename template.
サンプル
mktempコマンドのマニュアルに、
サンプルも載っているので参考にするといいでしょう。
EXAMPLES
The following sh(1) fragment illustrates a simple use of mktemp where the script
should quit if it cannot get a safe temporary file.
tempfoo=`basename $0`
TMPFILE=`mktemp /tmp/${tempfoo}.XXXXXX` || exit 1
echo "program output" >> $TMPFILE
To allow the use of $TMPDIR:
tempfoo=`basename $0`
TMPFILE=`mktemp -t ${tempfoo}` || exit 1
echo "program output" >> $TMPFILE
In this case, we want the script to catch the error itself.
tempfoo=`basename $0`
TMPFILE=`mktemp -q /tmp/${tempfoo}.XXXXXX`
if [ $? -ne 0 ]; then
echo "$0: Can't create temp file, exiting..."
exit 1
fi
trapコマンドについて
mktempコマンドは、ファイルやディレクトリを作成してくれますが、
使い終わったら自動で削除してくれるような機能はありませんので、
trapでrmコマンドを実行するようにすると良いでしょう。
trapコマンドは指定したコマンド文字列を、
特定のタイミングで実行させる事ができます。
よく使うのはEXITでしょう。
ShellScriptであれば、スクリプトが終了した際に実行される事になります。
trap 'echo "This message shows at exiting."' EXIT
もし、サブシェル内で利用すれば、
サブショル終了のタイミングでも実行できます。
まとめ
mktemp -d
コマンドで一時ディレクトリを作成できるtrap
コマンドでスクリプト終了時に一時ディレクトリ削除できる- サブシェルを使えば、特定の処理だけ一時ディレクトリで作業ができる