{{tag>[cli mktemp coreutils temporary-file shell]}}
====== mktemp ======
mktemp는 예측하기 어려운 이름으로 임시 파일이나 임시 디렉터리를 안전하게 생성하고 그 경로를 출력하는 command-line 도구다.
===== Summary =====
* 이름을 먼저 고른 뒤 파일을 만드는 방식에서 발생하는 race condition을 피하도록 파일이나 디렉터리를 원자적으로 생성한다.
* 기본 GNU 형식은 ''tmp.XXXXXXXXXX''이며, 생성된 경로는 stdout으로 출력된다.
* 생성한 임시 자원은 script 종료 시 ''trap''으로 정리하는 것이 좋다.
===== Installation =====
==== Debian / Ubuntu ====
''mktemp''는 GNU coreutils package에 포함된다.
sudo apt update
sudo apt install coreutils
==== RHEL / Fedora ====
sudo dnf install coreutils
==== macOS ====
macOS에는 BSD 계열 ''mktemp''가 기본 제공된다. GNU 구현이 필요하면 Homebrew의 coreutils formula를 설치한다. macOS 기본 command와 충돌하는 GNU command에는 ''g'' prefix가 붙으므로 GNU 구현은 일반적으로 ''gmktemp''로 실행한다.
brew install coreutils
gmktemp --version
==== Windows ====
GNU Coreutils가 공식 제공하는 native WinGet package는 없다. WSL을 사용하는 경우 해당 Linux distribution의 package manager로 ''coreutils''를 설치한다.
==== 설치 확인 ====
GNU 구현은 다음 명령으로 version을 확인할 수 있다. BSD 구현은 ''--version''을 지원하지 않을 수 있다.
mktemp --version
===== Usage =====
mktemp [OPTION]... [TEMPLATE]
* ''**mktemp** [OPTION]... [TEMPLATE]''
* GNU ''TEMPLATE''의 마지막 path component에는 연속된 ''X''가 3개 이상 있어야 한다.
* 마지막 연속 ''X''가 임의의 영숫자로 치환된다. template을 생략하면 GNU 구현은 ''tmp.XXXXXXXXXX''를 사용하고 ''--tmpdir''를 암시한다.
===== Options =====
* ''**-d, --directory**'': 임시 파일 대신 임시 디렉터리를 생성한다.
* ''**-q, --quiet**'': 생성 실패 진단 메시지를 숨긴다. exit status는 그대로 유지된다.
* ''**-p** DIR'', ''**--tmpdir=**DIR'': ''TEMPLATE''을 지정한 디렉터리 기준으로 해석한다.
* ''**--tmpdir**'': ''TMPDIR''이 설정되어 있으면 그 위치를, 아니면 ''/tmp''를 사용한다.
* ''**--suffix=**SUFFIX'': 생성 이름 뒤에 suffix를 붙인다. suffix에는 slash를 넣을 수 없다.
* ''**-u, --dry-run**'': 실제 객체를 만들지 않고 사용 가능한 이름만 출력한다. 이름 확인과 생성 사이에 race condition이 생기므로 보안이 필요한 script에서 사용하면 안 된다.
* ''**-t**'': template을 ''TMPDIR'' 또는 ''/tmp'' 아래의 단일 filename component로 해석하는 GNU legacy option이다. GNU에서는 ''--tmpdir'' 또는 ''-p''를 우선한다.
===== Examples =====
==== 임시 파일 생성과 자동 정리 ====
tmp_file=$(mktemp) || exit 1
trap 'rm -f -- "$tmp_file"' EXIT
printf '%s\n' 'temporary data' >"$tmp_file"
cat "$tmp_file"
변수 확장 결과에는 공백이 포함될 수 있으므로 경로 변수를 항상 quote한다.
==== 현재 디렉터리에 template으로 생성 ====
tmp_file=$(mktemp ./report.XXXXXX) || exit 1
printf '%s\n' "$tmp_file"
==== suffix가 있는 임시 파일 생성 ====
다음은 GNU ''mktemp'' 예시다.
tmp_file=$(mktemp --suffix=.json app.XXXXXX) || exit 1
printf '{}\n' >"$tmp_file"
==== 임시 디렉터리 생성과 자동 정리 ====
tmp_dir=$(mktemp -d) || exit 1
trap 'rm -rf -- "$tmp_dir"' EXIT
printf '%s\n' 'work data' >"$tmp_dir/result.txt"
''rm -rf'' 대상은 반드시 성공적으로 생성된 ''tmp_dir''처럼 범위가 확정된 변수여야 한다. 빈 값이나 검증되지 않은 경로를 재귀 삭제 대상으로 사용하지 않는다.
==== TMPDIR 존중하기 ====
GNU ''mktemp''에서 template을 생략하면 ''TMPDIR''을 우선한다.
mkdir -p -- "$PWD/.tmp"
tmp_file=$(TMPDIR="$PWD/.tmp" mktemp) || exit 1
printf '%s\n' "$tmp_file"
===== Troubleshooting =====
==== too few X's in template ====
GNU 구현에서는 template의 마지막 component에 연속된 ''X''가 3개 이상 있어야 한다.
mktemp ./job.XXXXXX
==== 생성 위치를 찾기 어려움 ====
''mktemp''는 생성 경로를 stdout으로 반환한다. command substitution으로 저장하거나 바로 출력해 확인한다.
tmp_dir=$(mktemp -d) || exit 1
printf 'temporary directory: %s\n' "$tmp_dir"
==== permission denied ====
대상 디렉터리가 존재하고 현재 사용자가 쓸 수 있는지 확인한다. GNU 구현에서 ''-p DIR''은 중간 디렉터리를 자동으로 만들지 않는다.
===== Compatibility =====
* ''mktemp''는 POSIX 표준 command가 아니며 GNU, BSD, BusyBox 구현의 option과 template 규칙이 다를 수 있다.
* GNU 전용 long option인 ''--suffix'', ''--tmpdir'', ''--version''에 의존하는 script는 macOS 기본 BSD 구현에서 그대로 동작하지 않을 수 있다.
* GNU/Linux와 macOS를 함께 지원하는 단순 script에서는 argument 없는 ''mktemp''와 디렉터리 생성용 ''mktemp -d''를 우선하고 대상 환경에서 검증한다.
* macOS의 ''-t'' 의미와 GNU의 deprecated ''-t'' 동작은 완전히 같다고 가정하지 않는다.
===== Deprecated / Legacy =====
* ''**mktemp** **-u** XXX'': 이름만 생성한 뒤 나중에 파일을 만드는 방식은 TOCTOU race condition에 취약하다.
* process ID ''$$''를 붙여 임시 filename 만들기: 이름이 예측 가능하며 공격자가 먼저 file이나 symbolic link를 만들 수 있다.
===== Help =====
++++ mktemp --help (GNU coreutils 8.30) |
Usage: mktemp [OPTION]... [TEMPLATE]
Create a temporary file or directory, safely, and print its name.
TEMPLATE must contain at least 3 consecutive 'X's in last component.
If TEMPLATE is not specified, use tmp.XXXXXXXXXX, and --tmpdir is implied.
Files are created u+rw, and directories u+rwx, minus umask restrictions.
-d, --directory create a directory, not a file
-u, --dry-run do not create anything; merely print a name (unsafe)
-q, --quiet suppress diagnostics about file/dir-creation failure
--suffix=SUFF append SUFF to TEMPLATE; SUFF must not contain a slash.
This option is implied if TEMPLATE does not end in X
-p DIR, --tmpdir[=DIR] interpret TEMPLATE relative to DIR; if DIR is not
specified, use $TMPDIR if set, else /tmp. With
this option, TEMPLATE must not be an absolute name;
unlike with -t, TEMPLATE may contain slashes, but
mktemp creates only the final component
-t interpret TEMPLATE as a single file name component,
relative to a directory: $TMPDIR, if set; else the
directory specified via -p; else /tmp [deprecated]
--help display this help and exit
--version output version information and exit
++++
===== See Also =====
* [[:bash]]
* [[:mkdir]]
* [[https://www.gnu.org/software/coreutils/manual/html_node/mktemp-invocation.html|GNU Coreutils: mktemp invocation]]
* [[https://formulae.brew.sh/formula/coreutils|Homebrew Formulae: coreutils]]
===== History =====
* codex:: 2026-08-17 mktemp의 안전한 임시 파일·디렉터리 생성, 정리, 설치, 호환성 문서를 추가했다.
{{indexmenu>.#1|js}}