GNU/Linux >> Tutoriels Linux >  >> Linux

Pourquoi la substitution de processus Bash ne fonctionne-t-elle pas avec certaines commandes ?

À l'occasion, la substitution de processus ne fonctionnera pas comme prévu. Voici un exemple :

Entrée :

gcc <(echo 'int main(){return 0;}')

Sortie :

/dev/fd/63: file not recognized: Illegal seek
collect2: error: ld returned 1 exit status

Entrée :

Mais cela fonctionne comme prévu lorsqu'il est utilisé avec une autre commande :

grep main <(echo 'int main(){return 0;}')

Sortie :

int main(){return 0;}

J'ai remarqué des échecs similaires avec d'autres commandes (c'est-à-dire que la commande qui attend le fichier de la substitution de processus ne peut pas utiliser /dev/fd/63 ou similaire). Cet échec avec gcc n'est que le plus récent. Existe-t-il une règle générale que je devrais connaître pour déterminer quand la substitution de processus échouera de cette manière et ne devrait pas être utilisée ?

J'utilise cette version de BASH sur Ubuntu 12.04 (j'ai également vu cela dans arch et debian) :
GNU bash, version 4.3.11(1)-release (i686-pc-linux-gnu)

Réponse acceptée :

Traiter les résultats de substitution dans un fichier spécial (comme /dev/fd/63 dans votre exemple) qui se comporte comme la fin de lecture d'un tube nommé. Ce fichier peut être ouvert et lu, mais pas écrit, pas recherché.

Les commandes qui traitent leurs arguments comme des flux purs fonctionnent alors que les commandes qui s'attendent à rechercher dans les fichiers qui leur sont donnés (ou à y écrire) ne fonctionneront pas. Le type de commande qui fonctionnera est ce qui est généralement considéré comme un filtre :cat , grep , sed , gzip , awk , etc… Un exemple de commande qui ne fonctionnera pas est un éditeur comme vi ou une opération de fichier comme mv .

gcc veut pouvoir effectuer un accès aléatoire sur ses fichiers d'entrée pour détecter dans quelle langue ils sont écrits. Si vous donnez à la place gcc un indice sur la langue du fichier d'entrée, il est heureux de diffuser le fichier :

gcc -x c <(echo 'int main(){return 0;}')

Le formulaire le plus simple et le plus direct sans substitution de processus fonctionne également :

echo 'int main(){return 0;}' | gcc -x c -

Notez que ce n'est pas spécifique à bash . Tous les shells prenant en charge la substitution de processus se comportent de la même manière.


Linux
  1. Et si "kill -9" ne fonctionne pas ?

  2. Mapper les métadonnées avec Avconv ne fonctionne pas ?

  3. Pourquoi Bash ne stocke-t-il pas les commandes commençant par des espaces ?

  4. Pourquoi "zip" dans une boucle For fonctionne-t-il lorsque le fichier existe, mais pas lorsqu'il n'existe pas ?

  5. Pourquoi Tomcat fonctionne-t-il avec le port 8080 mais pas 80 ?

La commande Rm dans le script Bash ne fonctionne pas avec la variable ?

Pourquoi `exit &` ne fonctionne pas ?

Pourquoi bash ne s'arrête-t-il pas en cas d'erreur pour les échecs dans la séquence de commandes court-circuitées ?

Pourquoi la bifurcation de mon processus entraîne-t-elle la lecture infinie du fichier

Pourquoi wget'ing une image me donne-t-il un fichier, pas une image ?

Pourquoi cette regex ne fonctionne-t-elle pas sous Linux ?