En ocasiones, la sustitución del proceso no funcionará como se esperaba. Aquí hay un ejemplo:
Entrada:
gcc <(echo 'int main(){return 0;}')
Salida:
/dev/fd/63: file not recognized: Illegal seek
collect2: error: ld returned 1 exit status
Entrada:
Pero funciona como se esperaba cuando se usa con un comando diferente:
grep main <(echo 'int main(){return 0;}')
Salida:
int main(){return 0;}
He notado fallas similares con otros comandos (es decir, el comando que espera que el archivo de la sustitución del proceso no pueda usar /dev/fd/63o similar). Este fracaso con gcces solo el más reciente. ¿Hay alguna regla general que deba tener en cuenta para determinar cuándo la sustitución del proceso fallará de esta manera y no debería usarse?
Estoy usando esta versión de BASH en Ubuntu 12.04 (también lo he visto en arch y debian):
GNU bash, versión 4.3.11 (1) -release (i686-pc-linux-gnu)

illegal seekparece la respuesta: lo|pipequebashapunta al programa ejecutado no es un archivo buscable. Probablemente si no puede tener éxitoecho data | command /dev/fd/0en un programa, entonces tendrá una suerte similar w /<(cmd). No proporciona un archivo en el disco, solo sustituye un argumento que apunta a un descriptor de archivo de tubería.gcc -xc <(echo 'int main(){return 0;}')(que establece el idiomaCexplícitamente).Respuestas:
La sustitución del proceso da como resultado un archivo especial (como
/dev/fd/63en su ejemplo) que se comporta como el final de lectura de una tubería con nombre. Este archivo puede abrirse y leerse, pero no puede escribirse ni buscarse.Los comandos que tratan sus argumentos como flujos puros funcionan mientras que los comandos que esperan buscar en los archivos que reciben (o que les escriben) no funcionarán. El tipo de comando que el trabajo es lo que se considera generalmente como un filtro:
cat,grep,sed,gzip,awk, etc ... Un ejemplo de un comando que no va a funcionar es un editor comovio una operación de archivo comomv.gccdesea poder realizar un acceso aleatorio en sus archivos de entrada para detectar en qué idioma están escritos. Si, en cambio, dagccuna pista sobre el idioma del archivo de entrada, se complace en transmitir el archivo:La forma más simple y directa sin sustitución del proceso también funciona:
Tenga en cuenta que esto no es específico de
bash. Todos los shells que admiten la sustitución de procesos se comportan de la misma manera.fuente
<()formato debe actuar como un archivo para todos los efectos. De hecho, no conozco ningún comando que espere un archivo con el que no esté satisfecho<(). Los que no funcionan son aquellos que esperan nombres de archivos , no archivos. Por ejemplo,grep -fespera un archivo y funciona bien con<().<()produce un nombre de archivo (la construcción se expande/proc/self/fd/somethingen mi sistema). Este nombre, cuando se abre, actúa como el final de lectura de una canalización con nombre (S_IFIFO) en lugar de un archivo normal (S_IFREG) en el que se admitenread()y otros, pero noseek().zshadmite una tercera forma de sustitución de procesos que utiliza archivos temporales especialmente para ese fin:gcc =(echo 'int main(){return 0;}')<(echo '...')pero no con<(git show ...). alguna idea de por qué podría ser?ld(que detecta formatos de objeto).-xno es una pista; Es una declaración. Si lo especifica-x f95, GCC pasará el archivo al compilador Fortran-95 independientemente de su nombre o contenido. Ver gcc.gnu.org/onlinedocs/gcc-8.1.0/gcc/Overall-Options.html