On 2010-10-21, James Mills <prolo...@shortcircuit.net.au> wrote: > On Thu, Oct 21, 2010 at 6:17 AM, Richard Gibbs ><richard.gi...@smooth-stone.com> wrote: >> If my python script is called with stdout (or stdin or stderr) redirected to >> a file, how can I find the filename under Linux??? Under Windows? > > I don't believe there is a way to do this.
There is, but it's not pretty. > The shell normally takes care of pipes. And it takes care of redirects. Which, importantly for this case, are not the same thing. > When you do: > > $ ./foo > /tmp/foobar > > You're telling your shell to write the stdout output of foo to the > file /tmp/foobar Not quite. You're telling the shell to attach the file /tmp/foobar to stdout before running the program foo. If the shell was reading data from foo's stdout and then writing it to /tmp/foobar, we'd be out of luck. But that's not what a redirect does. > sys.stdout won't actually tell you anything useful. It's normally > just a file descriptor. Ah, but file descriptors _can_ tell you something useful. :) The program below will print the filename(s) (if there are any) when stdout is a regular file. NB: to make it easy to test, it only searches below ".", so you'd probably want to widen the search if you're doing this in a real program. [Asking sys.stdout for its fileno is a bit redundant since it's defined to be 1 in the Unix world.] [I've no clue how to do this under Windows.] [I also don't know what the answer is to the question the OP should have asked. But, I suspect this is a case of asking for a method to implement the wrong solution to an unstated problem.] In any case, here's how do do "the wrong thing": ------------------------------------------------------------------------ #!/usr/bin/python import sys,os,stat write = sys.stderr.write # search for file(s) with given device/inode values def findFile(dev,ino): namelist = [] for root,dirs,files in os.walk("."): for name in files: path = os.path.join(root,name) statinfo = os.stat(path) fdev,fino = statinfo[stat.ST_DEV],statinfo[stat.ST_INO] if (dev,ino) == (fdev,fino): namelist.append(path) return namelist # get stat info of stdout, and if it's a regular file, search # filesystem under '.' for matching file(s) fd = sys.stdout.fileno() statinfo = os.fstat(fd) mode = statinfo[stat.ST_MODE] if stat.S_ISCHR(mode): write("stdout is a char device\n") elif stat.S_ISREG(mode): dev,ino = statinfo[stat.ST_DEV],statinfo[stat.ST_INO] write("stdout is a regular file on device %d inode %d\n" % (dev,ino)) write("filename(s): %s\n" % findFile(dev,ino)) elif stat.S_ISSOCK(mode): write("stdout is a socket\n") elif stat.S_ISFIFO(mode): write("stdout is a FIFO\n") else: write("stdout unknown type\n") -- http://mail.python.org/mailman/listinfo/python-list