56

Is there anyway I could write to tempfile and include it in a command, and then close/remove it? I would like to execute the command, eg: some_command /tmp/some-temp-file.

import tempfile
temp = tempfile.TemporaryFile()
temp.write('Some data')
command=(some_command temp.name)
temp.close()
starball
  • 20,030
  • 7
  • 43
  • 238
DGT
  • 2,604
  • 13
  • 41
  • 60

4 Answers4

92

Complete example.

import tempfile
with tempfile.NamedTemporaryFile() as temp:
    temp.write('Some data')
    if should_call_some_python_function_that_will_read_the_file():
       temp.seek(0)
       some_python_function(temp)
    elif should_call_external_command():
       temp.flush()
       subprocess.call(["wc", temp.name])

Update: As mentioned in the comments, this may not work in windows. Use this solution for windows

Update 2: Python3 requires that the string to be written is represented as bytes, not str, so do instead

temp.write(bytes('Some data', encoding = 'utf-8')) 
Per Christian Henden
  • 1,514
  • 1
  • 16
  • 26
balki
  • 26,394
  • 30
  • 105
  • 151
  • 13
    Just want to add that if the command is replaced by some Python code (like a function call) make sure you do temp.seek(0) so if that function tries to read the content it won't be empty handed. – Fortepianissimo Mar 19 '13 at 20:39
  • 4
    +1 for the use of _with_. Is there a reason why the examples in the [documentation](https://docs.python.org/2/library/tempfile.html) doesn't use _with_? – cbare Oct 01 '14 at 19:34
  • 2
    Make sure you consider this from the [docs](https://docs.python.org/3.4/library/tempfile.html#tempfile.NamedTemporaryFile): "Whether the name can be used to open the file a second time, while the named temporary file is still open, *varies across platforms* (it can be so used on Unix; it cannot on Windows NT or later)." Note that using the `with` statement keeps the tempfile open when you're calling `command`, and as such your code's portability is impacted. – Jens Feb 17 '15 at 19:22
38

If you need a temporary file with a name you have to use the NamedTemporaryFile function. Then you can use temp.name. Read http://docs.python.org/library/tempfile.html for details.

Samuel Katz
  • 24,066
  • 8
  • 71
  • 57
25

Try this:

import tempfile
import commands
import os

commandname = "cat"

f = tempfile.NamedTemporaryFile(delete=False)
f.write("oh hello there")
f.close() # file is not immediately deleted because we
          # used delete=False

res = commands.getoutput("%s %s" % (commandname,f.name))
print res
os.unlink(f.name)

It just prints the content of the temp file, but that should give you the right idea. Note that the file is closed (f.close()) before the external process gets to see it. That's important -- it ensures that all your write ops are properly flushed (and, in Windows, that you're not locking the file). NamedTemporaryFile instances are usually deleted as soon as they are closed; hence the delete=False bit.

If you want more control over the process, you could try subprocess.Popen, but it sounds like commands.getoutput may be sufficient for your purposes.

phooji
  • 10,086
  • 2
  • 38
  • 45
  • 3
    This answer (especially `delete=False` & `close()`) is key information for the Windows case. Thank you. – davidA Jul 22 '16 at 06:02
3

Use a NamedTemporaryFile and its member name instead. A regular TemporaryFile isn't even guaranteed to have a name, due to the way Unix filesystems work.

Community
  • 1
  • 1
Fred Foo
  • 355,277
  • 75
  • 744
  • 836