How can the standard input of one program be passed as an arg to another?

Let’s say a program exists, which takes two arguments; input file and output file.

What if I don’t wish to save this output file to disk, but rather pass it straight to stdin of another program. Is there a way to achieve this?

A lot of commands I come across on Linux provide an option to pass ‘-‘ as the output file argument, which does what I’ve specified above. Is this because passing the stdin of a program as an argument is not possible? If it is, how do we do it?

An example of how I would image using this is:

pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" stdin(echo)

The shell I’m using is bash.

Asked By: Dziugas

||

If the program supports writing to any file descriptor even if it can’t seek, you can use /dev/stdout as the output file. This is a symlink to /proc/self/fd/1 on my system. File descriptor 1 is stdout.

Answered By: TiCPU

From the pdftotext man page:

If text-file is ´-‘, the text is sent to stdout.

So in this case all you need is:

pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" -

Or if you want to pipe this to STDIN of another program:

pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" - | another_prog

Using - as substitute for a filename is a convention many utilities follow (including pdftotext) when we want input from STDIN or output to STDOUT. However not all utilities follow this convention. In that case the idiomatic way to do this in bash is to use a process substitution:

my_utility "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" >( cat )

Here the >( ) behaves largely like a file passed to my_utility, but instead of being a real file, the stream is piped into the stdin of the contained process, i.e. cat. So here, the text should ultimately output as required.

Use of cat almost always sets off UUOC alarm bells on forums like this. I contend that if the utility does not support -, then this is a useful use of cat, though if there are any ways to do this process substitution without the cat, then I’m all ears ;-).

However, if (as the question states) the ultimate destination of of the stream is STDIN of another program, then the cat can be eliminated:

my_utility "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" >( another_prog )
Answered By: Digital Trauma

If your shell supports them, the simplest way of doing such manipulations would be to use process substitution: <(…) and >(…). This works in bash, zsh and ksh and possibly other shells. For example:

$ sort <(printf "bncnan")
a
b
c
$ ls
foo
$ cp <(find . -name foo) bar
$ ls
bar  foo

However, this won’t help in the example you state since pdftotext will save in a text file. While your best choice (apart from the obvious one of using -) is to use /dev/stdout as suggested by @TiCPU, you could also use another shell feature. The construct !:N refers to the Nth argument of the previous command. Therefore, you could do:

$ pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf"  out.txt
$ cat !:2
Answered By: terdon
cmd tty

tty returns the name of the terminal connected to stdout.

Answered By: jas
Categories: Answers Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.