8

This works perfectly :

./foo | ./bar

But I'd like something like that :

./bar <| ./foo

So I can pipe the other way around and change foo's arguments faster in command line.

The pipe needs to be realtime - my foo program does never return.

Is this possible ?

  • Not really a pipe but you might use ./bar <(./foo) – Lambert Oct 3 '16 at 10:15
  • 2
    or ./bar < <(./foo) if bar is a script. – Lambert Oct 3 '16 at 10:26
  • 5
    How would that be faster? Are you just looking for the shell shortcuts like Ctrl+A to go to the beginning and Alt+F to move forward one word at a time? – terdon Oct 3 '16 at 11:18
  • Yet shell shortcuts may be useful, I still have to press those key multiple times to get the cursor on the desired argument, whereas having the cursor directly at the end makes me win seconds – Bilow Oct 3 '16 at 14:46
  • It takes you seconds to type Ctrl+A? – chepner Oct 4 '16 at 0:10
2
./bar < <( ./foo )

For example: cat < <(echo "hello there!")

To understand how it works, consider parts of the script separately.

This syntax: cat < /path/to/file will read the file /path/to/file and pipe it as stdin to cat.

This syntax: <(echo "hello there!") means to execute the command and attach the stdout to a file descriptor like /dev/fd/65. The result of the whole expression is a text like /dev/fd/65, and a command run in parallel and feeding that file descriptor.

Now, combined, the script will run the right command, pipe it to a file descriptor, convert that file descriptor to stdin for the left command, and execute the left command.

There is no overhead that I'd know of, it's exactly the same as a | b, just syntactic sugar.

| improve this answer | |
9

A simple and proper way can be to define a foobar function,

foobar () { ./foo "$@" | ./bar ; }

(either in the command line, as needed, or in some startup scripts, such as ".bashrc" for example). Then whenever you do :

foobar "this"  that   "and this also"

it will do

./foo  this   that   "and this also" | ./bar
| improve this answer | |
  • 1
    Yup, I do this all the time to make it easy to up-arrow and edit the part of the command I want to change, without having to ctrl-left-arrow all the way to it. You can even leave the function definition as part of the command: foobar() { printf '%s\n' -x "$1" -y "$2" blah blah "${@:3}" | grep -v 123; }; foobar a b abc 'cd ef'. So you can easily tweak the function definition if you think of something else. ("${@:3}" expands to the positional parameters starting with 3, skipping the two we already used.) – Peter Cordes Oct 3 '16 at 15:03
  • You can do useful stuff like local IFS= inside a function, and calculate some variables based on the function args. – Peter Cordes Oct 3 '16 at 15:05
4

I think you could do something like that with a named pipe:

mypipe=$(mktemp -d /tmp/XXXXXX)/pipe
mkfifo $mypipe
grep something < $mypipe & tail > $mypipe -f  some_input_file 
rm $mypipe

or put the unchanging part of the command in a shell script:

./foo "$@" | ./bar

and give the arguments to foo on the script command line:

./myscript <args to foo>
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.