sophie: A cartoon-like representation of a girl standing on a hill, with brown hair, blue eyes, a flowery top, and blue skirt. ☀ (Default)
[personal profile] sophie posting in [community profile] command_liners
Most people in here will probably know how to pipe output from one command to another:

command 1 | command2

However, what if command2 doesn't allow reading from standard input, and only supports filenames? How can you do this without writing to a file?

It turns out that you can do this in bash and ksh by using the <(command) syntax. For example, the above command can be written:

command2 <(command1)

This will execute command1 in a subshell, and at the same time, call command2 with a file descriptor looking something like /dev/fd/63. When command2 reads from that, it'll get the output of command1.

At first this doesn't seem too useful, but this means that you can do nifty things like this:

diff -u <(sort filea.txt) <(sort fileb.txt)

Which will sort filea.txt and fileb.txt, and then diff the outputs - all without writing a single file.

Note that if the subshells require user input, this isn't going to work, so you can't use this to capture user input and pass it to a script which would otherwise require a filename. However, as long as this isn't the case, everything should work smoothly.

[edit: Oh, and I should mention that, unlike piping, you can execute several commands in the subshell. For example:

rev <(echo wheeness; sleep 2; echo blarg)

This also demonstrates how both the subshell and the main process run simultaneously; the output is "sseneehw", followed by a delay of 2 seconds, followed by "gralb".]

[edit 2: See this comment for an example of how to run multiple commands via piping!]

Date: 2010-11-06 08:50 am (UTC)
rpdom: Me wearing my first pair of reading glasses (Default)
From: [personal profile] rpdom
I didn't know that. A very handy hint, thank you!

(I love this community)

Date: 2010-11-06 09:23 am (UTC)
jld: (banjo)
From: [personal profile] jld

comm -3 <(cd foo && find . | sort) <(cd bar && find . | sort)

That, and variants on it, I've become somewhat fond of when the need arises.

Date: 2010-11-06 02:30 pm (UTC)
pne: A barcode representing the digits "688700207914", derived from my Dreamwidth userid (geeky)
From: [personal profile] pne

Date: 2010-11-06 03:35 pm (UTC)
pauamma: Cartooney crab holding drink (Default)
From: [personal profile] pauamma
Oh, and I should mention that, unlike piping, you can execute several commands in the subshell.
( echo -n furr; echo fu ) | tr a-z n-za-m

Jes sayin'. :-)

Date: 2010-11-06 08:22 pm (UTC)
brownbetty: (Default)
From: [personal profile] brownbetty
Hah! Super, this allowed me to send files through strings of sed and tr straight to lp. Brilliant.


command_liners: A command line prompt with a blinking cursor after it, green against black. (Default)
Command Liners

September 2014

1415 1617181920

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Nov. 28th, 2015 12:25 am
Powered by Dreamwidth Studios