Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do some programs not accept process substitution for input files?

I'm trying to use process substitution for an input file to a program, and it isn't working. Is it because some programs don't allow process substitution for input files?

The following doesn't work:

bash -c "cat meaningless_name"
    >sequence1
    gattacagattacagattacagattacagattacagattacagattacagattaca
    >sequence2
    gattacagattacagattacagattacagattacagattacagattacagattaca
bash -c "clustalw -align -infile=<(cat meaningless_name) -outfile=output_alignment.aln -newtree=output_tree.dnd"
    (Less verbose output, finishing with:
    No sequences in file. No alignment!

But the following controls do work:

bash -c "clustalw -align -infile=meaningless_name -outfile=output_alignment.aln -newtree=output_tree.dnd"
    (Verbose output, finishing with:
    CLUSTAL-Alignment file created  [output_alignment.aln]
bash -c "cat <(cat meaningless_name) > meaningless_name2"
diff meaningless_name meaningless_name2
    (No output: the two files are the same)
bash -c "clustalw -align -infile=meaningless_name2 -outfile=output_alignment.aln -newtree=output_tree.dnd"
    (Verbose output, finishing with:
    CLUSTAL-Alignment file created  [output_alignment.aln]

Which suggest that process substitution itself works, but that the clustalw program itself doesn't like process substitution - perhaps because it creates a non-standard file, or creates files with an unusual filename.

Is it common for programs to not accept process substitution? How would I check whether this is the issue?

I'm running GNU bash version 4.0.33(1)-release (x86_64-pc-linux-gnu) on Ubuntu 9.10. Clustalw is version 2.0.10.

like image 215
Andrew Grimm Avatar asked Nov 25 '10 06:11

Andrew Grimm


2 Answers

Process substitution creates a named pipe. You can't seek into a named pipe.

like image 117
Dennis Williamson Avatar answered Nov 08 '22 05:11

Dennis Williamson


Yes. I've noticed the same thing in other programs. For instance, it doesn't work in emacs either. It gives "File exists but can not be read". And it's definitely a special file, for me /proc/self/fd/some_number. And it doesn't work reliably in either less nor most, with default settings.

For most:

most <(/bin/echo 'abcdef')

and shorter displays nothing. Longer values truncate the beginning. less apparently works, but only if you specify -f.

I find zsh's = much more useful in practice. It's syntactically the same, except = instead of <. But it just creates a temporary file, so support doesn't depend on the program.

EDIT:

I found zsh uses TMPPREFIX to choose the temporary filename. So even if you don't want your real /tmp to be tmpfs, you can mount one for zsh.

like image 36
Matthew Flaschen Avatar answered Nov 08 '22 07:11

Matthew Flaschen