How create a temporary file in shell script?
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/$FDis 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
what does the `exec 3> "$tmpfile"` do? Isn't that only useful if the tmpfile is a stand-alone script?
@AlexejMagura That command creates the file descriptor which is to be used instead of a (regular) file path in order to solve the problem.
I want to put the second style into a shell function. Since the process isn't exiting, does that mean I need to close the file descriptor at the end of the function call?
@eckes You can use `cat <3` or something similar. Remember stdin and stdout just happen to live on 1 and 2, you can move them around to other descriptors easily.
@CMCDragonkai You can do `mkdir /tmp/del ; cd /tmp/del ; rmdir /tmp/del; ls -l /proc/self/cwd` but it seems less useful than with files because you cannot store anything in such a directory (except for "deleted files").
@HaukeLaging what do you mean by store anything except for deleted files. I was wondering why can't you store files in a directory descriptor. Is it the shell, the syscall, or the actual filesystem preventing this?
@CMCDragonkai In contrast to regular files you cannot delete non-empty directories.
@HaukeLaging I'm primarily looking for a way to do an atomic directory commit. Being able to use a temporary directory for staging and then performing a `rename` op to atomically commit is cool. But if that temporary directory is guaranteed to be deleted when the process is, then I don't have to worry about external garbage collection.
" You can use cat <3 or something similar." actually that reads from a file named 3 @dragon788. Also, `cat <&3` will give `Bad file descriptor`. I'd appreciate it if you either fix it or remove it; misinformation doesn't much help.
@HaukeLaging will you update this to show how to read from the file descriptor? Automatically deleting a file you write to and don't read from isn't much good.