Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Post History

77%
+5 −0
Q&A When a command takes filenames as argument, how can I avoid creating temporary files?

This other answer uses process substitutions. Not every shell supports this feature. If your OS provides pathnames for file descriptors (/dev/fd/N or /proc/self/fd/N) then you can use them to achie...

posted 11mo ago by Kamil Maciorowski‭

Answer
#1: Initial revision by user avatar Kamil Maciorowski‭ · 2023-06-13T08:35:28Z (11 months ago)
[This other answer][1] uses process substitutions. Not every shell supports this feature. *If* your OS provides pathnames for file descriptors (`/dev/fd/N` or `/proc/self/fd/N`) then you can use them to achieve the desired result without process substitution and without temporary files:

    ls /home/alice | { ls /home/bob | diff /dev/fd/4 -; } 4<&0 </dev/null

The result of `ls /home/alice` would be piped to the next command (group of commands `{ }` in our case) via stdin of the next command, but we make it available as file descriptor 4 (`4<&0`). We also redirect stdin to `/dev/null` in case something tries to read from it while it shouldn't. In our case this "something" is the second `ls`. While `ls` does not try to read from its stdin, in general a command may.

Now the result of `ls /home/alice` is available to `diff` via its file descriptor 4. By passing `/dev/fd/4` as an operand we tell `diff` to use the file (pipe in this case) associated with the descriptor. Note in some systems opening `/dev/fd/4` results in duplicating the descriptor (i.e. referring to the same [open file description][2]), but in other systems (particularly in Linux) opening `/dev/fd/4` results in opening the file *anew* (i.e. creating a fresh new open file description). In our case this nuance does not matter, our command should work either way.

The result of `ls /home/bob` is piped to `diff` via its stdin. By `-` we tell `diff` to read from its stdin. Note `-` means "stdin" only because `diff` interprets `-` this way. Not all commands interpret `-` as "stdin", so in general you may want to use `/dev/fd/0`.

  [1]: https://linux.codidact.com/posts/288328/288329#answer-288329
  [2]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_258