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.

I am learning about file descriptors for the case of Linux, and I was wondering if there is any command showing a complete list that allows me to know where is each one redirected to in this moment.
Maybe some info like:

0  -->  <stdin
1  -->  >stdout
2  -->  >stderr
3  -->  >MyFileForWriting
4  -->  <MyFileForReading

I have found this thread that requires lsof, but it could be useful to have another method not depending on that command, if it exists.
I need this info concerning to Linux (I will try it too for CygWin, that does not include the 'lsof' tool until now, but behaves mostly like a POSIX compliant operating system).

share|improve this question
2  
Does cygwin /proc filesystem emulation? If so, check out /proc/PID/fd/ –  cpugeniusmv Apr 6 at 0:45
1  
I would imagine it would work for any cygwin-launched processes. –  cpugeniusmv Apr 6 at 0:53
1  
OK - I don't get it - /proc/self/fd is no good? What about /dev/fd/${num} - is that a cygwin thing? –  mikeserv Apr 6 at 1:53
2  
If lsof isn't installed, the answer is to install lsof. Pretty much every unix variant provides a way to do this, but the way is wildly different between variants. The lsof authors provide a single command that works everywhere. If you're going from file name to process, you can also use fuser. If you're only interested in Cygwin, use Process Explorer. –  Gilles Apr 6 at 22:35
2  
@SopalajodeArrierez This only works on Linux, on Cygwin which emulates that aspect of Linux, and on a few SysV unices. It doesn't work on other unices, in particular *BSD. In contrast, lsof has been ported to any unix you can name and several you can't. –  Gilles Apr 6 at 22:56
show 8 more comments

2 Answers 2

The /proc file system will list exactly this information:

$ ls -l /proc/self/fd
total 0
lrwx------ 1 michas users 1 Apr  6 04:44 0 -> /dev/pts/0
lrwx------ 1 michas users 1 Apr  6 04:44 1 -> /dev/pts/0
lrwx------ 1 michas users 1 Apr  6 04:44 2 -> /dev/pts/0
lr-x------ 1 michas users 1 Apr  6 04:44 3 -> /proc/6934/fd
$ ls -l /proc/self/fd 2>/dev/null <<<foo |cat
total 0
lr-x------ 1 michas users 1 Apr  6 04:45 0 -> /tmp/sh-thd-361068043 (deleted)
l-wx------ 1 michas users 1 Apr  6 04:45 1 -> pipe:[136729]
l-wx------ 1 michas users 1 Apr  6 04:45 2 -> /dev/null
lr-x------ 1 michas users 1 Apr  6 04:45 3 -> /proc/6952/fd

If you are interested in some other process just replaces "self" with the corresponding PID.

share|improve this answer
1  
One important item of note is that when shell scripting, doing something like ls /proc/self will show the FDs of ls, not of the shell invoking ls. It's an easy trap to fall into and why I never use it. The way to look at the shell would be ls -l /proc/$$/fd –  Patrick Apr 6 at 2:47
    
Correct. But exactly this fact allows easy redirection for demonstration purposes. –  michas Apr 6 at 2:50
add comment

@Patrick points out in the comments below that access to these files requires a non-default kernel compile-time option. I was not aware of this having only now discovered them at all. Though I do know that my kernel package was installed via package-manager and so it must be included in the default build at least for one distribution - so your mileage may vary, especially if Cygwin is involved.

I think you'd get a more complete listing if, at least, you included /proc/self/map_files:

% sudo ls -al ${p=/proc/$$}/map_files | sudo sort -t\> -ubk2,2  

lr-------- 1 mikeserv mikeserv ? 64 Apr  5 21:07 400000-4a6000 -> /usr/bin/zsh
lr-------- 1 mikeserv mikeserv ? 64 Apr  5 21:07 7f5e05aa3000-7f5e05ac3000 -> /usr/lib/ld-2.19.so
lr-------- 1 mikeserv mikeserv ? 64 Apr  5 21:07 7f5e04b88000-7f5e04b8c000 -> /usr/lib/libattr.so.1.1.0
lr-------- 1 mikeserv mikeserv ? 64 Apr  5 21:07 7f5e04d8d000-7f5e04f2b000 -> /usr/lib/libc-2.19.so
lr-------- 1 mikeserv mikeserv ? 64 Apr  5 21:07 7f5e0589f000-7f5e058a3000 -> /usr/lib/libcap.so.2.24
lr-------- 1 mikeserv mikeserv ? 64 Apr  5 21:07 7f5e0569b000-7f5e0569e000 -> /usr/lib/libdl-2.19.so
lr-------- 1 mikeserv mikeserv ? 64 Apr  5 21:07 7f5e05135000-7f5e05235000 -> /usr/lib/libm-2.19.so
lr-------- 1 mikeserv mikeserv ? 64 Apr  5 21:07 7f5e05436000-7f5e05496000 -> /usr/lib/libncursesw.so.5.9
lr-------- 1 mikeserv mikeserv ? 64 Apr  5 21:07 7f5e0497c000-7f5e04987000 -> /usr/lib/libnss_files-2.19.so
lr-------- 1 mikeserv mikeserv ? 64 Apr  5 21:07 7f5e05afa000-7f5e05c83000 -> /usr/lib/locale/locale-archive
lr-------- 1 mikeserv mikeserv ? 64 Apr  5 21:07 7f5e0450c000-7f5e0452f000 -> /usr/lib/zsh/5.0.5/zsh/complete.so
lr-------- 1 mikeserv mikeserv ? 64 Apr  5 21:07 7f5e038e0000-7f5e038ee000 -> /usr/lib/zsh/5.0.5/zsh/complist.so
lr-------- 1 mikeserv mikeserv ? 64 Apr  5 21:07 7f5e036cb000-7f5e036db000 -> /usr/lib/zsh/5.0.5/zsh/computil.so
lr-------- 1 mikeserv mikeserv ? 64 Apr  5 21:07 7f5e03cf3000-7f5e03cfc000 -> /usr/lib/zsh/5.0.5/zsh/parameter.so
lr-------- 1 mikeserv mikeserv ? 64 Apr  5 21:07 7f5e03aef000-7f5e03af2000 -> /usr/lib/zsh/5.0.5/zsh/stat.so
lr-------- 1 mikeserv mikeserv ? 64 Apr  5 21:07 7f5e04101000-7f5e04103000 -> /usr/lib/zsh/5.0.5/zsh/terminfo.so
lr-------- 1 mikeserv mikeserv ? 64 Apr  5 21:07 7f5e04731000-7f5e04773000 -> /usr/lib/zsh/5.0.5/zsh/zle.so
lr-------- 1 mikeserv mikeserv ? 64 Apr  5 21:07 7f5e03efe000-7f5e03f00000 -> /usr/lib/zsh/5.0.5/zsh/zleparameter.so
lr-------- 1 mikeserv mikeserv ? 64 Apr  5 21:07 7f5e04304000-7f5e0430b000 -> /usr/lib/zsh/5.0.5/zsh/zutil.so

That's a sorted unique list. The list looks very close to this:

% lsof -p ${p##*/}

COMMAND   PID     USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
zsh     23748 mikeserv  cwd    DIR    0,3        0 7800580 /proc/23748/map_files
zsh     23748 mikeserv  rtd    DIR   0,33      254     256 /
zsh     23748 mikeserv  txt    REG   0,33   705496 1281560 /usr/bin/zsh
zsh     23748 mikeserv  mem    REG   0,30          1281560 /usr/bin/zsh (path dev=0,33)
zsh     23748 mikeserv  mem    REG   0,30          1281593 /usr/lib/zsh/5.0.5/zsh/computil.so (path dev=0,33)
zsh     23748 mikeserv  mem    REG   0,30          1281592 /usr/lib/zsh/5.0.5/zsh/complist.so (path dev=0,33)
zsh     23748 mikeserv  mem    REG   0,30          1281579 /usr/lib/zsh/5.0.5/zsh/stat.so (path dev=0,33)
zsh     23748 mikeserv  mem    REG   0,30          1281576 /usr/lib/zsh/5.0.5/zsh/parameter.so (path dev=0,33)
zsh     23748 mikeserv  mem    REG   0,30          1281596 /usr/lib/zsh/5.0.5/zsh/zleparameter.so (path dev=0,33)
zsh     23748 mikeserv  mem    REG   0,30          1281582 /usr/lib/zsh/5.0.5/zsh/terminfo.so (path dev=0,33)
zsh     23748 mikeserv  mem    REG   0,30          1281587 /usr/lib/zsh/5.0.5/zsh/zutil.so (path dev=0,33)
zsh     23748 mikeserv  mem    REG   0,30          1281591 /usr/lib/zsh/5.0.5/zsh/complete.so (path dev=0,33)
zsh     23748 mikeserv  mem    REG   0,30          1281595 /usr/lib/zsh/5.0.5/zsh/zle.so (path dev=0,33)
zsh     23748 mikeserv  mem    REG   0,30          1936654 /usr/lib/libnss_files-2.19.so (path dev=0,33)
zsh     23748 mikeserv  mem    REG   0,30            23825 /usr/lib/libattr.so.1.1.0 (path dev=0,33)
zsh     23748 mikeserv  mem    REG   0,30          1936661 /usr/lib/libc-2.19.so (path dev=0,33)
zsh     23748 mikeserv  mem    REG   0,30          1936618 /usr/lib/libm-2.19.so (path dev=0,33)
zsh     23748 mikeserv  mem    REG   0,30            24316 /usr/lib/libncursesw.so.5.9 (path dev=0,33)
zsh     23748 mikeserv  mem    REG   0,30          1936627 /usr/lib/libdl-2.19.so (path dev=0,33)
zsh     23748 mikeserv  mem    REG   0,30          1249113 /usr/lib/libcap.so.2.24 (path dev=0,33)
zsh     23748 mikeserv  mem    REG   0,30          1936645 /usr/lib/ld-2.19.so (path dev=0,33)
zsh     23748 mikeserv  mem    REG   0,30          1720288 /usr/lib/locale/locale-archive (path dev=0,33)
zsh     23748 mikeserv    0u   CHR  136,6      0t0       9 /dev/pts/6
zsh     23748 mikeserv    1u   CHR  136,6      0t0       9 /dev/pts/6
zsh     23748 mikeserv    2u   CHR  136,6      0t0       9 /dev/pts/6
zsh     23748 mikeserv   10u   CHR  136,6      0t0       9 /dev/pts/6

Well, the filenames do anyway. I think a lot of this functionality could be easily reproduced with just stat, possibly ps and/or the pid of interest. Obviously there's the fd directory, as mentioned in the other answer, and you can get root, cwd, from the /proc/self filesystem as well.

share|improve this answer
    
I would clarify that this shows memory mapped files, not normal opened files (accessible via file descriptor). It's also not enabled in most kernels. It defaults to n (disabled), and isn't even accessible unless CONFIG_EXPERT is also enabled. –  Patrick Apr 6 at 5:05
    
Even /proc/maps? I just found this stuff so I'm learning about it - but the question seemed to me to ask how to replicate lsof's output. In any case, lsof lists them as mem-mapped FDs which indicated file descriptors. Also, if you cat one of these memory blocks you'll see the actual currently mapped file - or the blocks of it in memory, anyway. –  mikeserv Apr 6 at 5:13
    
Note that your replacement for lsof only lists the memmapped files and does not list the file descriptors the process has open (the bottom 4 lines of your lsof output) that the OP is specifically asking about. –  casey Apr 6 at 5:36
    
@casey It's not a replacement - personally, I wouldn't use ls at all - I point out at the bottom that the files included in the other answer should be included also and the current working directory and so on. I also suggest stat and/or ps would probably be the goto tools here - not ls - did you read it? Actually I point that out top and bottom - I just called it a more complete listing. But lsof does call them file descriptors FDs, anyway –  mikeserv Apr 6 at 5:39
    
Yes I did, I read both the Q (did you?) and your A, which why I was compelled to comment. The Q isn't asking to reproduce the lsof output, it is looking to get the file descriptor information via a different command than lsof. To be clear, I'm not disagreeing with anything you say in your A, I'm just pointing out much of it just isn't relevant to the question posed. –  casey Apr 6 at 5:55
show 6 more comments

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.