By Ryan C. Thompson

2009-11-22 01:57:00 8 Comments

I'm trying to write something like Perl Audio Converter, so I need to be able to decode every relevant audio format to wav (PCM) and then encode wav to every relevant audio format. I'd like to do this in parallel, by piping the output of the decoder directly to the input of the encoder. Most decoders have an option to decode to stdout, but not all of them do. Some insist on outputting to a file.

So my question is, how can I trick a program that will only output to a specified file into using stdout instead? Also, the complementary question: how can I trick a program that requires in input file into reading from stdin?

Would this be impossible because the program might want to seek back and forth within the output?

Incidentally, Perl Audio Converter sidesteps this problem by always using an intermediate wav file, which means that it never does decoding and encoding in parallel, even for formats that support it.

PS: Yes, there's a reason I don't want to just use Perl Audio Converter, but it's not relevant to the question.


@Employed Russian 2009-11-22 02:02:02

On Linux, you can give /proc/self/fd/1 as a "file" output.
That should work for any program that doesn't try to seek in the output.

Some programs do seek in output (e.g. to write summary info at the start of the file once decoding is complete), and this seek will fail with anything other than a real file.

If the program checks the return value of fseek or lseek (as it should), the program will likely return an error. If it doesn't, it will likely exit successfully, but will create erroneous output (e.g. with incorrect summary info in the beginning, and extra "junk" at the end).

@Roger Pate 2009-11-22 02:04:57

There's also /dev/std{in,out}.

@Ryan C. Thompson 2009-11-23 01:43:49

So to chain two programs together, I could do something like this? prog1 --outfile /proc/self/fd/1 | prog2 --infile /proc/self/fd/0

@user215054 2009-11-22 02:11:26

Create a pipe and assign output to the pipe

@nos 2009-11-22 02:09:40

Make a named pipe.

mkfifo /tmp/mypipe

Instead of doing e.g.

echo foo | wc -c 

you can use it as a file

echo foo > /tmp/myfifo &
wc -c /tmp/myfifo

(whichever is started first will block until the other end of the pipe is opened) But you're right, if the program does require an actual file for e.g. seeking, this will not work.

@outis 2009-11-22 02:06:59

Some OSes, such as Unix variants and the win32 family, support named pipes. You might be able to use them instead of stdout/stdin.

@Ryan C. Thompson 2009-11-22 02:10:17

If a program takes an output file argument, there's a good chance that it will delete any file with that name and then create its own. Wouldn't that prevent a named pipe from working?

@nos 2009-11-22 02:26:22

Most program creating output files does not delete the file first, it just opens it with the CREATE flag and perhaps the TRUNC flag. Which creates the file if it doesn't exist, and truncates its content if it does exist. This works fine for fifos as well.

Related Questions

Sponsored Content

49 Answered Questions

[SOLVED] How do I find all files containing specific text on Linux?

7 Answered Questions

[SOLVED] How to redirect and append both stdout and stderr to a file with Bash?

30 Answered Questions

[SOLVED] How to change the output color of echo in Linux

11 Answered Questions

[SOLVED] grep, but only certain file extensions

16 Answered Questions

10 Answered Questions

[SOLVED] How to redirect output to a file and stdout

11 Answered Questions

[SOLVED] How can I pipe stderr, and not stdout?

7 Answered Questions

[SOLVED] Redirect Windows cmd stdout and stderr to a single file

Sponsored Content