The question here is the bold sentence below. Suppose I'm trying to do this:
diff -u <(some command) {mystery-syntax}
I am diffing the output of some command and some data that comes from standard input—for instance, a copy-and-paste in the terminal. Like this:
$ diff -u <(echo foo) {mystery-syntax}
bar
[Ctrl-D]
--- /dev/fd/63 2021-11-04 11:28:19.360366909 -0700
+++ /dev/fd/62 2021-11-04 11:28:19.360366909 -0700
@@ -1 +1 @@
-foo
+bar
What actual syntax is the {mystery-syntax} meta-token covering?
The diff utility doesn't use the - convention for specifying standard input, so we cannot use that.
One answer is: /dev/fd/0.
$ diff -u <(echo foo) /dev/fd/0
bar
[Ctrl-D]
--- /dev/fd/63 2021-11-04 11:31:02.837040697 -0700
+++ /dev/fd/0 2021-11-04 11:30:56.807964644 -0700
@@ -1 +1 @@
-foo
+bar
OK, so we have it working in one way, on systems that have Linux-style /dev/fd. But is there a way without referencing the /dev filesystem, which is a system-specific implementation detail? I believe Bash process substitution is supported on systems which have mechanisms other than /dev/fd. The manual states that:
Process substitution is supported on systems that support named pipes (FIFOs) or the /dev/fd method of naming open files.
For instance, the obvious:
diff <(echo foo) <(cat)
doesn't work; for whatever reason, even though the <(cat) process substitution needs only the output side of cat, cat is nevertheless being invoked in such a way that it has no standard input:
$ diff -u <(echo foo) <(cat)
cat: -: Input/output error
--- /dev/fd/63 2021-11-04 11:33:59.303347814 -0700
+++ /dev/fd/62 2021-11-04 11:33:59.303347814 -0700
@@ -1 +0,0 @@
-foo
There are some "clever" behaviors here, too. If we explicitly redirect
/dev/fd/0intocat's input, that is still borked somehow:$ diff -u <(echo foo) <(cat < /dev/fd/0) cat: -: Input/output errorBut! If we give
catit a here-document as its standard input, there is no interference:$ diff -u <(echo foo) <(cat <<<"bar") --- /dev/fd/63 2021-11-04 11:40:03.612616179 -0700 +++ /dev/fd/62 2021-11-04 11:40:03.612616179 -0700 @@ -1 +1 @@ -foo +bar
diff - -assumes that the two arguments are the same object and doesn't read from standard input twice; but that is neither here nor there with regard to this Q&A.) – Kaz Nov 12 '21 at 20:27-convention really isn't supported. – Kaz Nov 12 '21 at 20:27diffwith-does not work. It's a convention required by the POSIX standard. – Kusalananda Nov 12 '21 at 20:28diff - -case and saw that it returns without reading anything. (Why I don't remember is that I wrote this question maybe two weeks ago, and just noticed today that I hadn't finished submitting it, due to getting a warning while closing numerous browser tabs.) So I thought, oh, it's just treating-as a file name, and optimizing the case of a file being diffed with itself. – Kaz Nov 12 '21 at 20:29diff -s - -and you will see what happens (in short, you are comparing the same data against itself, so there should not be any output). – Kusalananda Nov 12 '21 at 20:34/dev/fdkernel-specific thing. – Kaz Nov 12 '21 at 21:39