Je soupçonne que le pourquoi a beaucoup à faire avec la vision / conception qui a façonné Unix (et par conséquent Linux), et les avantages qui en découlent.
Nul doute qu’il ya un avantage non négligeable sur le plan des performances à ne pas créer un processus supplémentaire, mais je pense qu’il ya plus à faire: Early Unix avait une métaphore "tout est un fichier", ce qui présente un avantage non évident mais élégant si vous le regardez. cela du point de vue du système plutôt que du point de vue des scripts shell.
Supposons que vous ayez votre null
programme de ligne de commande et /dev/null
le nœud de périphérique. Du point de vue des scripts shell, le foo | null
programme est réellement utile et pratique , et foo >/dev/null
prend un peu plus de temps à taper et peut sembler étrange.
Mais voici deux exercices:
Nous allons mettre en œuvre le programme en null
utilisant des outils Unix existants et /dev/null
- facile: cat >/dev/null
. Terminé.
Pouvez-vous mettre /dev/null
en œuvre en termes de null
?
Vous avez absolument raison de dire que le code C destiné à supprimer une entrée est trivial, il est donc difficile de comprendre pourquoi il est utile de disposer d'un fichier virtuel pour la tâche.
Prenez en compte que presque tous les langages de programmation doivent déjà utiliser des fichiers, des descripteurs de fichiers et des chemins de fichiers, car ils faisaient partie du paradigme d'Unix "tout est un fichier" depuis le début.
Si tout ce que vous avez sont des programmes qui écrivent sur stdout, eh bien, le programme ne se soucie pas de les rediriger vers un fichier virtuel qui englobe toutes les écritures ou un canal vers un programme qui englobe toutes les écritures.
Maintenant, si vous avez des programmes qui utilisent des chemins de fichiers pour lire ou écrire des données (ce que font la plupart des programmes), et que vous souhaitez ajouter une fonctionnalité "entrée vide" ou "supprimer cette sortie" à ces programmes, /dev/null
cela est gratuit.
Notez que son élégance est de réduire la complexité du code de tous les programmes impliqués - pour chaque cas d'utilisation commun mais particulier que votre système peut fournir en tant que "fichier" avec un "nom de fichier" réel, votre code peut éviter d'ajouter une commande personnalisée. -ligne les options et les chemins de code personnalisés à gérer.
Une bonne ingénierie logicielle dépend souvent de la recherche de métaphores «naturelles» pour résumer certains éléments d’un problème d’une manière qui facilite la réflexion mais reste souple , de sorte que vous puissiez résoudre pratiquement le même éventail de problèmes de niveau supérieur sans avoir à consacrer temps et énergie mentale à réimplémenter en permanence des solutions aux mêmes problèmes de niveau inférieur.
« Tout est un fichier » semble être une telle métaphore pour l' accès aux ressources: Vous appelez open
d'un chemin donné dans un espace de noms heirarchical, en obtenant une référence (descripteur de fichier) à l'objet, et vous pouvez read
et write
, etc sur les descripteurs de fichiers. Votre stdin / stdout / stderr sont également des descripteurs de fichier qui viennent d’être pré-ouverts pour vous. Vos canaux ne sont que des fichiers et des descripteurs de fichiers, et la redirection de fichiers vous permet de coller tous ces éléments ensemble.
Unix a tout autant réussi en partie à cause de la manière dont ces abstractions ont bien fonctionné et /dev/null
est mieux compris en tant que partie intégrante de cet ensemble.
Post-scriptum Il convient de regarder la version Unix de "Tout est un fichier", entre autres, /dev/null
comme les premiers pas vers une généralisation plus souple et plus puissante de la métaphore mise en œuvre dans de nombreux systèmes qui ont suivi.
Par exemple, sous Unix, des objets spéciaux de type fichier, tels que ceux-ci, /dev/null
devaient être implémentés dans le noyau lui-même, mais il s'avère assez utile d’exposer les fonctionnalités sous forme de fichier / dossier qui, depuis lors, ont permis de créer plusieurs systèmes qui permettent aux programmes pour faire ça.
L'un des premiers était le système d'exploitation Plan 9, créé par les mêmes personnes qui ont créé Unix. Plus tard, GNU Hurd a fait quelque chose de similaire avec ses "traducteurs". Pendant ce temps, Linux finissait par obtenir FUSE (qui s’est également propagé aux autres systèmes traditionnels).
cat foo | bar
est bien pire (à l'échelle) quebar <foo
.cat
est un programme trivial, mais même un programme trivial crée des coûts (certains d’entre eux sont spécifiques à la sémantique FIFO - car les programmes ne peuvent passeek()
entrer dans les FIFO, par exemple, un programme qui pourrait être mis en œuvre efficacement avec la recherche peut aboutir à des opérations beaucoup plus coûteuses lorsqu’un pipeline est créé, avec un périphérique de type caractère,/dev/null
il peut simuler ces opérations, ou avec un fichier réel, il peut les implémenter, mais une FIFO ne permet aucun type de traitement contextuel).