Do some programs not accept process substitution f

2019-02-17 22:05发布

问题:

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.

回答1:

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.



回答2:

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