1

Consider a command like foo -in /path/to/infile -out /path/to/outfile, that you'd like to pass strings to rather than using temp files. It may be called a lot causing much disk access, or is related to encryption where you don't want to write sensitive data to disk (or deal with encrypted and/or ram disks, etc).

Is there a way to give it stdin and get the output in stdout,
something like echo "abc" | foo -in &0 -out &1?

I know there are file descriptors you can redirect data to and from, like echo "foo" 1>&2. And that things like xargs can pass strings as arguments. But is it possible to pass a standard file descriptor as a file path in some way? If I can read and write to stdin/out as a file, why not be able to get its "virtual" file path?

  • What is so special about foo? that you have to specify stdin as input. Can't it act on its own? Are there cases that stdin could be file input also? – Inian Nov 23 '18 at 3:11
  • Umm here look at this: superuser.com/questions/747884/… – Michael Prokopec Nov 23 '18 at 3:16
  • @Inian I mentioned a couple of examples in my question (disk wear, sensitive data). Imagine foo being a simple string transform tool but only takes file paths. It would be inconvenient to use mktemp, etc for such simple things. @MichaelProkopec I know how to create scripts that use files and stdin/out as input/output. My question was about existing binaries that only work with file paths. – Beejor Nov 24 '18 at 3:42
3

You can use special files /dev/stdin or /dev/fd/0 for stdin, and /dev/stdout or /dev/fd/1 for stdout.

In your example:

echo "abc" | foo -in /dev/fd/0 -out /dev/fd/1

The availability of these special files depends on the O.S. you're on, but on Linux (and on most Linux distributions) you shouldn't have problem finding or using them.

These files are "virtual", in the sense that writing to one of those will not write data to disk. Opening one of these special files is equivalent to calling the dup(2) syscall, which duplicates the existing file descriptor onto a new one.

  • Thanks; I knew there was a /dev/null, etc. but not a /dev/stdin. All this time using the shell and I had no idea! – Beejor Nov 24 '18 at 3:36
  • On a related note, and just to be sure... are these "virtual" files that exist only in memory, and are not actually physically written to disk? Are there any cases in normal use where stdin/out would be written to disk? Since sensitive data may be piped through them (aside from any terminal logs/cache, etc). – Beejor Nov 24 '18 at 3:46
  • 1
    @Beejor Yes they are "virtual" files. Writing to them won't go to disk (well, unless stdout was redirected to disk in first place...) I updated the answer with more details. – filbranden Nov 24 '18 at 3:57
  • 1
    On Linux, it's possible to see where these files are pointing because they pretend to be symlinks, you can use readlink() on them. You can ls -l /dev/fd/ or ls -l /proc/<PID>/fd/ of some other process. You can also find some more info, notably file offset (if pointing to file), by reading corresponding files under /proc/<PID>/fdinfo/ (github.com/Xfennec/progress is a cool use of the latter ability). man proc is your friend. – Beni Cherniavsky-Paskin May 7 at 11:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.