web-dev-qa-db-fra.com

Pourquoi les utilitaires obligatoires POSIX ne sont-elles pas intégrées à la coquille?

Le but de cette question est de répondre à une curiosité, de ne pas résoudre un problème informatique particulier. La question est la suivante: pourquoi les utilitaires obligatoires POSIX ne sont-elles pas couramment intégrées à la mise en œuvre de Shell?

Par exemple, j'ai un script qui lit essentiellement quelques petits fichiers texte et vérifie qu'ils sont correctement formatés, mais il faut 27 secondes pour exécuter, sur ma machine, en raison d'une quantité importante de manipulation de chaîne. Cette manipulation de chaîne fait des milliers de nouveaux processus en appelant divers utilitaires, d'où la lenteur. Je suis assez confiant que si certains des utilitaires ont été construits, à savoir grep, sed, cut, tr et expr , alors le script fonctionnerait dans une seconde ou moins (sur la base de mon expérience en C).

Il semble qu'il y aurait de nombreuses situations dans lesquelles construire ces utilitaires dans la différence entre si une solution dans le script Shell ait une performance acceptable.

Évidemment, il y a une raison pour laquelle il a été choisi de ne pas créer ces utilitaires intégrés. Peut-être avoir une version d'un utilitaire à un niveau système évite d'avoir plusieurs versions inégales de cet utilitaire utilisé par divers coquilles. Je ne peux vraiment pas penser à de nombreuses autres raisons de garder les frais généraux de créer autant de nouveaux processus, et POSIX définit suffisamment les services publics qu'il ne semble pas avoir une grande partie d'un problème d'une implémentation différente, tant qu'ils sont chaque POSIX Conforme. Au moins pas aussi gros problème que l'inefficacité d'avoir tant de processus.

47
Kyle

Les scripts Shell ne devraient pas fonctionner avec ce type de vitesse. Si vous souhaitez améliorer la vitesse de votre script, essayez-la à Perl. Si cela reste trop lent, vous devrez passer à une langue statistique typée telle que Java ou C ou écrire un module C pour Perl qui exécute les pièces trop lentes.

Shell est le premier niveau de prototypage, si vous pouvez prouver le concept avec une coque, puis déplacez-vous à un meilleur langage de script qui puisse faire une vérification plus limitée qui prendrait des acres de shell.

Un système d'exploitation UNIX devrait inclure de nombreux petits programmes qui font des tâches bien définies qui constituent une image plus grande. C'est une bonne chose en compartimente des programmes plus importants. Jetez un coup d'œil à Qmail, par exemple et comparez cela avec Sendmail. Qmail est composé de nombreux programmes:

http://www.nrg4u.com/qmail/the-big-qmail-picture-103-p1.gif

Exploitation du démon de réseau ne vous aiderait pas à exploiter le gestionnaire de files d'attente.

11
Ed Neville

Pourquoi les utilitaires obligatoires POSIX ne sont-elles pas intégrées à Shell?

Parce que doit être conforme à Posix, un système est requis 1 fournir la plupart des utilitaires en tant que commandes autonomes.

Les avoir encastrés impliqueraient qu'ils doivent exister dans deux endroits différents, à l'intérieur de la coquille et à l'extérieur. Bien sûr, il serait possible de mettre en œuvre la version externe à l'aide d'une enveloppe de script shell sur la construction, mais qui désavantagerait les applications non coquillantes appelant les utilitaires.

Notez que busybox a pris le chemin que vous avez suggéré en implémentant de nombreuses commandes en interne et en fournissant la variante autonome à l'aide de liens vers lui-même. Un problème est que la commande peut être assez importante, les implémentations sont souvent un sous-ensemble de la norme, ne sont donc pas conformes.

Notez également qu'au moins ksh93 , bash et zsh aller plus loin en fournissant des méthodes personnalisées pour la coque exécutée pour charger dynamiquement des étages de bibliothèques partagées. Techniquement, rien n'empêche alors tous les services publics de POSIX d'être mis en œuvre et mis à disposition comme produits.

Enfin, de nouveaux processus de frai sont devenus une opération assez rapide avec des OSES modernes. Si vous êtes vraiment touché par une question de performance, il pourrait y avoir des améliorations pour que vos scripts fonctionnent plus rapidement.

1POSIX.1-2008

Toutefois, toutes les utilitaires standard , y compris les intégrées régulières dans le tableau, mais pas les constructions spéciales décrites dans des services publics intégrés spéciaux , doit être mis en œuvre de manière à ce qu'elles puissent être accessibles via la famille EXEC de fonctions telle que définie dans le volume des interfaces système de POSIX.1-2008 et peut être invoqué directement par ces utilitaires standard qui le nécessitent (env, recherches, Nice, NOHUP, TIME, XARGS).

67
jlliagre

À partir du Manuel de référence Bash ,

Les commandes intégrées sont nécessaires pour mettre en œuvre des fonctionnalités impossibles ou gênantes pour obtenir avec des utilitaires distincts.

Comme je suis sûr que vous avez bien entendu, la philosophie UNIX repose fortement sur plusieurs applications que toutes ont une fonctionnalité limitée. Chaque intégré a une très bonne raison pour laquelle il est construit. Tout le reste n'est pas. Je pense qu'une classe de questions plus intéressante est le long des lignes de: "Pourquoi exactement est pwd intégré?"

9
Stephen C

Les gars de AT & T se sont demandé la même chose

Si vous regardez l'historique de la boîte à outils logicielle AT & T (en dormant actuellement sur GitHub depuis que l'équipe principale est partielle), c'est exactement ce qu'ils ont fait avec le shell AT & T Korn, a.k.a. ksh93.

La performance faisait toujours partie de la motivation des Maintenants KSH93 et ​​lors de la construction de KSH, vous pouvez choisir de créer de nombreux utilitaires communs de POSIX comme des bibliothèques chargées de manière dynamique. En contraignant ces commandes à un nom de répertoire comme /opt/ast/bin, vous pouvez contrôler quelle version de la commande serait utilisée, basée sur la position de ce nom de répertoire dans $PATH.

Exemples:

cat chmod chown cksum cmp cp cut date expr fmt head join ln
mkdir mkfifo mktemp mv nl od paste rm tail tr uniq uuencode wc

La liste complète peut être trouvée dans le référentiel GitHub ast .

Notez que la plupart des outils AST ont leur propre provenance et diffèrent fortement des implémentations de GNU les plus courantes. L'équipe de recherche AT & T ait respecté les normes officielles, qui était la voie à l'interopérabilité lorsque vous ne pouviez pas partager le code.

8
Henk Langeveld

Nous n'avons donc pas eu de ressources sur le maréchal pour optimiser l'outil d'origine, pour répondre à chaque désir spécifique. Je suppose que ce que nous devons expliquer, c'est combien ce désir spécifique aurait coûté de mettre en œuvre.

POSIX définit suffisamment les services publics qu'il ne semble pas avoir une grande partie d'un problème d'une implémentation différente.

c'est une mauvaise hypothèse :-p.

Les systèmes postuls continuent de devenir plus puissants et plus pratiques pour de bonnes raisons; En tant que norme après-la-loi, il n'atteint jamais réellement.

Ubuntu a démarré un effort pour passer à une coquille POSIX dépouillée pour les scripts, pour optimiser l'ancien processus de démarrage du système VIED SYSTÈME. Je ne dis pas que cela a échoué, mais cela déclenche de nombreux insectes qui devaient être nettoyés: "Bashismes", scripts qui ont couru sous /bin/sh Tout en supposant que les fonctionnalités bash étaient disponibles.

POSIX SH n'est pas un bon langage de programmation à usage général. Son but principal est de bien fonctionner comme une coque interactive. Dès que vous commencez à enregistrer vos commandes à un script, soyez conscient de vous approcher un Turing Tarpit . Par exemple. Il n'est pas possible de détecter les défaillances au milieu d'un pipeline normal . bash ajouté set -o pipefail Pour cela, mais ce n'est pas à POSIX.

Des caractéristiques similaires utiles mais non standardisées sont fournies par presque tous les utilitaires plus complexes que true.

Pour la classe de tâche que vous décrivez, vous pouvez dessiner une ligne rugueuse à Awk, Perl, et aujourd'hui Python. Différents outils ont été créés et ont évolué de manière indépendante. Vous attendriez-vous par exemple GNU Awk doit-il être démesuré dans un dépôt liboutilexixé?

Je ne dis pas que nous avons maintenant une approche universellement meilleure que je peux vous indiquer. J'ai une tache douce pour python. Awk est étonnamment puissant, même si certaines fonctionnalités sont spécifiques à GNU awk. Mais le point est que le traitement de grand nombre de chaînes individuellement (probablement des lignes des fichiers) n'était pas un objectif de conception de la coquille POSIX.

6
sourcejedi

Il y a aussi la question de: quel shell construiriez-vous?

La plupart des systèmes UNIX/Linux ont plusieurs coquilles différentes qui sont développées indépendamment (SH/BASH/KORN/???). Si vous construisez les outils dans la coquille, vous vous retrouveriez avec une implémentation différente de ces outils pour chaque coquille. Cela causerait des frais généraux et vous risquez de vous retrouver avec différentes fonctionnalités/bugs de manière par exemple GREP, en fonction de la coquille que vous avez utilisée pour l'appeler.

2
MTilsted

Beaucoup ont bien répondu. Je n'ai l'intention que de complimenter ces réponses. Je pense que la philosophie Unix est que A Outil Devrait faire une chose et le faire bien. Si l'on essaie de faire un outil tout englobant, c'est plus d'endroits d'échec de lot. La fonctionnalité de limitation de cette manière fait un ensemble d'outils fiable.

En outre, considérons, si la fonctionnalité comme SED ou grep ont été construits dans la coque, seraient-ils aussi faciles à invoquer à partir de la ligne de commande quand vous souhaitez ce?

En terminant, envisagez certaines des fonctionnalités que vous souhaitez être à bash, est en bash. Par exemple, la possibilité de faire correspondre à Bash est implémentée à l'aide de l'opérateur = ~ Opérateur binaire (voir grammaire de shell dans la page manuelle Pour plus, spécifiquement, référence à la discussion de la [[]] construire pour si). Par exemple très rapide, disons que je cherche un fichier pour 2 chiffres hexagonaux:

while read line; do
    if [[ $line =~ 0x[[:xdigit:]]{2} ]]; then
        # do something important with it
    fi
done < input_file.txt

Comme pour SED-AIM FONCTIONALITÉ, regardez sous l'expansion des paramètres dans l'en-tête d'expansion de la même page homme. Vous verrez une richesse de choses que vous pouvez faire qui rappelle SED. J'utilise le plus souvent SED pour rendre un changement de type de substitution au texte. S'appuyant sur ce qui précède:

# this does not take into account the saving of the substituted text
# it shows only how to do it
while read line; do
    ${line/pattern/substitution}
done < input_file.txt

En fin de compte, c'est ce qui précède "mieux" que?

grep -E "[[:xdigit:]]{3}" input_file.txt
sed -e 's/pattern/substitution/' input_file.txt
1
Andrew Falanga

C'est, je suppose qu'un accident historique.

Lorsque Unix a été créé à la fin des années 1960 et au début des années 1970, les ordinateurs n'avaient pas autant de mémoire qu'aujourd'hui. Il aurait été possible, à l'époque, de mettre en œuvre toutes ces fonctionnalités en tant que shell comité, mais en raison de la limitation de la mémoire, ils auraient dû limiter la quantité de fonctionnalité qu'ils pouvaient mettre en œuvre, ou risquer de sortir de la mémoire et/ou des ordures d'échange. problèmes.

D'autre part, en mettant en œuvre la fonctionnalité donnée en tant que programmes distincts, et en faisant les deux appels de système requis pour le démarrage d'un nouveau processus que possible, ils pourraient créer un environnement de script qui n'a pas ces problèmes et qui fonctionne toujours à des raisons raisonnables. la vitesse.

Bien sûr, une fois que ces choses sont mises en œuvre en tant que processus distincts, les gens les démarreront à partir de programmes qui sont non obus, et ils doivent ensuite rester comme ça, ou tout à coup, tout ce logiciel commence à rompre.

Cela ne veut pas dire que vous ne pouvez pas implémenter certaines fonctionnalités deux fois, cependant, et bien certains obus impliquent certaines fonctionnalités censées être un programme externe en tant que coquille intégrée; E.G., Bash met en œuvre la commande echo comme intégré, mais il y a aussi un /usr/bin/echo

1
Wouter Verhelst