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
Also!

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
Oooh...

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.

Profile

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

December 2013

S M T W T F S
1234567
891011121314
15161718192021
222324252627 28
293031    

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 29th, 2014 08:40 am
Powered by Dreamwidth Studios