Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

While running a script, I want to create a temporary file in /tmp directory.

After execution of that script, that will be cleaned by that script.

How to do that in shell script?

share|improve this question

4 Answers 4

up vote 9 down vote accepted
tmpfile=$(mktemp /tmp/abc-script.XXXXXX)
: ...
rm "$tmpfile"

You can make sure that a file is deleted when the scripts exits (including kills and crashes) by opening a file descriptor to the file and deleting it. The file keeps available (for the script; not really for other processes but /proc/$PID/fd/$FD is a work-around) as long as the file descriptor is open. When it gets closed (which the kernel does automatically when the process exits) the filesystem deletes the file.

tmpfile=$(mktemp /tmp/abc-script.XXXXXX)
exec 3>"$tmpfile"
rm "$tmpfile"
: ...
echo foo >&3
share|improve this answer
    
Good answer, elegant solution with the file descriptor in case of a crash +1 –  chaos 2 days ago
    
/proc - except for systems that don't have it. –  Dennis Williamson 2 days ago

If you're on system which has mktemp, you should use it as other answers.

With POSIX toolchest:

umask 0177
tmpfile=/tmp/"$0"."$$"."$(awk 'BEGIN {srand();printf "%d\n", rand() * 10^10}')"
trap 'rm -f -- "$tmpfile"' INT TERM HUP EXIT
: > "$tmpfile"
share|improve this answer
    
What happens if EXIT is the only hook for trap? –  Hauke Laging 2 days ago
    
@HaukeLaging: tmpfile still be removed before script exit, but not when script received other signals. –  cuonglm 2 days ago
    
That's not what happens here (GNU bash, Version 4.2.53). –  Hauke Laging 2 days ago
    
@HaukeLaging: What do you mean That's not what happens? –  cuonglm 2 days ago
    
The EXIT trap is triggered in any case. May differe from shell to shell, though. –  Hauke Laging 2 days ago

Some shells have the feature built-in.

zsh

zsh's =(...) form of process substitution uses a temporary file. For instance =(echo test) expands to the path of a temporary file that contains test\n.

$ {cat $file; ls -l /dev/fd/3; echo test2 >&3; cat $file} 3<> ${file::==(echo test)}
test
lrwx------ 1 stephane stephane 64 Jan 30 11:19 /dev/fd/3 -> /tmp/zshMLbER0
test2

That file is automatically removed, once the command has finished.

bash/zsh on Linux.

Here-files or here-strings in bash and zsh are implemented as deleted temporary files.

So if you do:

exec 3<<< test

The file descriptor 3 is connected to a deleted temporary file that contains test\n.

You can get its content with:

cat <&3

If on Linux, you can also read or write to that file via /dev/fd/3

$ exec 3<<< test
$ cat <&3
test
$ echo foo > /dev/fd/3
$ cat /dev/fd/3
foo

(some other shells use pipes, or may use /dev/null if the here doc is empty).

share|improve this answer
    
Bash also has process substitution using <() –  WinnieNicklaus 2 days ago
    
@WinnieNicklaus, yes, but that doesn't use temporary files so is irrelevant here. Process substitution was introduced by ksh, copied by bash and zsh, and zsh extended it with a 3rd form: =(...). –  Stéphane Chazelas 2 days ago

Use mktemp to create a temporary file or directory:

temp_file=$(mktemp)

Or for a direcotry:

temp_dir=$(mktemp -d)

At the end of the script you have to delete the temporary file/dir:

rm ${temp_file}
rm -R ${temp_dir}

mktemp creates file in the /tmp directory or in the drectory given with the --tmpdir argument.

share|improve this answer
1  
You can use trap "rm -f $temp_file" 0 2 3 15 right after creating the file so that when the script exits or is stopped with ctrl-C the file is still removed. –  wurtel 2 days ago
    
@wurtel What happens if EXIT is the only hook for trap? –  Hauke Laging 2 days ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.