Here’s a little bash trick you might not be aware of.
If you wrap a command in
), you get back something that looks like a file name;
$ echo <(ls) /dev/fd/63
now, that’s not a file, but a file descriptor – a temporary path that unix programs can be tricked into treating like a file.
For example, you can
cat the file descriptor just as you would a file:
$ cat <(ls) Applications Desktop Documents Downloads
cat thinks it’s reading a file –
cat /dev/fd/63 – but it’s actually streaming the output of a command.
So with this trick, any program that takes a file parameter can take a command output. Eg;
curlsome web content
lsto describe files
grepto modify an existing file
This can be useful when you have a program that takes multiple input files, like diff;
$ diff <(ls src) <(ls src.bak) 3d2 < canto34-syntax.test.ts 5d3 < canto34.test.ts 7d4 < example.test.ts
So here I’ve listed the contents of two directories of source files, and I can see that
src has three more files in it than
src.bak. Now that’s hard to do otherwise!
Or consider this example – I’ve got two files I know differ only by indentation:
$ diff src/example.ts src.bak/example.ts | wc -l 82
so, lots of differences. But can I prove they’re the same after trimming?
$ diff <(sed 's|^ *||' src/example.ts) <(sed 's|^ *||' src.bak/example.ts) <no output>
Ok then! I’ve used
sed to trim leading whitespace from both files, and now the diff is empty – the files are basically the same.