How create a temporary file in shell script?

  • 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?

  • 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
    

    Good answer, elegant solution with the file descriptor in case of a crash +1

    `/proc` - except for systems that don't have it.

    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?

    How do you read from the created FD?

    @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.

    Can this work against directories, like a directory descriptor?

    @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.

    @DanielFarrell I asked your question separately and got an answer here.

    Note that the latter technique probably does not work on Cygwin or Mingw, because the Windows semantics for file deletions are different.

License under CC-BY-SA with attribution


Content dated before 6/26/2020 9:53 AM