Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

... Well, you can pass a string to exec into a command. in fact, unix has its own map like command based on this. It's called xargs.


You can, but that's a different thing - creating a new shell as a child of the command, rather than talking to the parent shell of the command.


Why would you want to do that? I'm kind of curious. I mean, I'm sure you have an application, I just can't think of one. Blub effect, I guess.


I've hit a number of small "oh, I could do that if..." use cases over the years; none is really immediately springing to mind.

There are things that a shell function can do that a spawned program cannot - mostly to do with affecting shell state. Updating shell variables and opening file descriptors are obvious examples.


This is one of the reasons shell languages feel kind of functional. But they're not really designed like a functional language so they feel kind of clunky.

On the subject of "oh, I could do that if..." I know exactly how you feel. I really want the ability to pass multiple filestreams to a command, so you could, say, use cat on the outputs of two commands. Assuming the syntax was @`<pipeline>`, It would like something like this:

foo|grep bar|cat @`baz|grep bar`|sort -rn|tail

The above script assumes that the commands foo and baz are generating lines with time signatures at the start, and then checking for the most recent entries. I chose the @` syntax for its similarity to the lisp @, syntax, but it could be anything. Unfortunately, I think the only way to do this would be to monkey-patch either open(2) or fopen(2), probably both, which would be a Really Bad Idea (tm).


I'm not exactly sure what semantics you intend, it seems like you might be able to spell this

    { foo; baz; } | grep bar | sort -rn | tail
or, in bash only:

    cat <(foo | grep bar) <(baz | grep bar) | sort -rn | tail
This is assuming you didn't intend interleaving, for which the second syntax would work but you'd need something other than cat.


the <(...) syntax seems to be what I was looking for, passing a stream/pipeline to a function where a filename was expected. Hey, you learn something every day.

EDIT: Unless you're just piping both of them to STDIN. piping two files to STDIN is useful, just not as useful as the thing that I wanted. This seems to be what you're doing.


It sets up a fifo, and passes in one end of it by name:

    $ echo <(:) <(:)
    /dev/fd/63 /dev/fd/62
So yeah, should be what you want for that use case :)

As I mentioned though, it's a bashism.


Now I'm going to have to build a portable version of that. It shouldn't be too hard.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: