В некоторых случаях процесс замены не будет работать должным образом. Вот пример:
Входные данные:
gcc <(echo 'int main(){return 0;}')
Выход:
/dev/fd/63: file not recognized: Illegal seek
collect2: error: ld returned 1 exit status
Входные данные:
Но он работает, как и ожидалось, когда используется с другой командой:
grep main <(echo 'int main(){return 0;}')
Выход:
int main(){return 0;}
Я заметил подобные сбои с другими командами (то есть команда, ожидающая файл от подстановки процесса, не может использоваться /dev/fd/63
или подобна). Этот сбой gcc
только самый последний. Есть ли какое-то общее правило, о котором я должен знать, чтобы определить, когда подстановка процесса потерпит неудачу и не должна использоваться?
Я использую эту версию BASH в Ubuntu 12.04 (я также видел это в arch и debian):
GNU bash, версия 4.3.11 (1) -релиз (i686-pc-linux-gnu)
illegal seek
выглядит как ответ -|pipe
этоbash
указывает на то, что исполняемая программа не является доступным для поиска файлом. вероятно, если вы не можете успешноecho data | command /dev/fd/0
в программе, то вам повезет с /<(cmd)
. Он не предоставляет файл на диске - он просто заменяет аргумент, который указывает на дескриптор файла канала.gcc -xc <(echo 'int main(){return 0;}')
(который устанавливает языкC
явно).Ответы:
Подстановка процесса приводит к специальному файлу (как
/dev/fd/63
в вашем примере), который ведет себя как конец чтения именованного канала. Этот файл можно открывать и читать, но не писать, не искать.Команды, которые рассматривают свои аргументы как чистые потоки, работают, в то время как команды, которые ожидают искать в файлах, которые им дают (или записывают в них), не будут работать. Вид команды , которая будет работать то , что обычно считается фильтр
cat
,grep
,sed
,gzip
,awk
и т.д. ... Пример команды , которая не будет работать является редактором , какvi
и операция файл какmv
.gcc
хочет иметь возможность произвольного доступа к своим входным файлам, чтобы определить, на каком языке они написаны. Если вместо этого вы дадитеgcc
подсказку о языке входного файла, он будет рад передать файл:Более простая, более простая форма без подстановки процесса также работает:
Обратите внимание, что это не относится к
bash
. Все оболочки, поддерживающие процесс замены, ведут себя одинаково.источник
<()
Формат должен действовать как файл для всех намерений и целей. На самом деле, я не знаю ни одной команды, которая ожидает файл, который не будет удовлетворен<()
. Те, которые не работают, ожидают имена файлов , а не файлов. Например,grep -f
ожидает файл и прекрасно работает с<()
.<()
выдает имя файла (конструкция распространяется/proc/self/fd/something
на мою систему). При открытии это имя действует как конец чтения именованного канала (S_IFIFO
), а не как обычный файл (S_IFREG
), который поддерживаетread()
и другие, но не поддерживаетseek()
.zsh
поддерживается третья форма замещения процесса, которая использует временные файлы специально для этой цели:gcc =(echo 'int main(){return 0;}')
<(echo '...')
но не с<(git show ...)
. Любая идея, почему это может быть?ld
(который обнаруживает форматы объектов).-x
это не намек; это декларация. Если вы укажете-x f95
, GCC передаст файл компилятору Fortran-95 независимо от его имени или содержимого. См. Gcc.gnu.org/onlinedocs/gcc-8.1.0/gcc/Overages-Options.html