Pourquoi ls
nécessite- t-il un processus distinct pour son exécution? Je connais la raison pour laquelle des commandes comme cd
ne peuvent pas être exécutées par le mécanisme de forking mais y a-t-il un mal si elles ls
sont exécutées sans forking?
ls
cd-command
fork
crisron
la source
la source
ls
un programme externeecho *
ouecho * .*
(selon les options du shell), il répertorie les fichiers sans bifurquer.ls-F
qui agit commels -F
. C'est là pour l'efficacité. Vous obtenez toujours-F
ce qui est généralement une bonne idée. Si vous spécifiez toute autre option, elle renvoie à la commande externe.Réponses:
La réponse est plus ou moins
ls
un exécutable externe. Vous pouvez voir son emplacement en exécutanttype -p ls
.Pourquoi n'est-il pas
ls
intégré au shell, alors? Eh bien, pourquoi devrait-il en être ainsi? Le travail d'un shell n'est pas d'englober toutes les commandes disponibles, mais de fournir un environnement capable de les exécuter. Certains shells modernes ontecho
,printf
et leurs semblables en tant que builtins, qui ne doivent pas être techniquement intégrés, mais qui le sont pour des raisons de performances lorsqu'ils sont exécutés de manière répétée (principalement en boucles serrées). Sans les rendre intégrés, le shell devrait bifurquer et exécuter un nouveau processus pour chaque appel, ce qui pourrait être extrêmement lent.À tout le moins, l'exécution
ls
, un exécutable externe, nécessite l'exécution d'une des exécutions système de la famille exec. Vous pouvez le faire sans bifurquer, mais cela remplacerait le shell principal que vous utilisez. Vous pouvez voir ce qui se passe dans cette instance en procédant comme suit:Puisque l'image de processus de votre shell est remplacée, le shell actuel n'est plus accessible après cela. Pour que le shell puisse continuer à s'exécuter après avoir exécuté ls, la commande doit être intégrée au shell.
Le fork permet de remplacer un processus qui n'est pas votre shell principal, ce qui signifie que vous pouvez continuer à exécuter votre shell par la suite.
la source
echo
,printf
, etc.cd
pas un exécutable externe?cd
exécutable externe dans les systèmes d'exploitation compatibles POSIX ( voir ici ). Si vous voulez réellement chdir () dans le processus en cours, cependant, vous devez l'intégrer dans le shell.ls
externe, mais il peut également être implémenté dans un shell. Voir busybox.Le manuel de référence Bash déclare:
Autrement dit, les shells sont conçus pour inclure uniquement des commandes intégrées si:
La
ls
commande ne correspond à aucune des exigences ci-dessus.Cependant , il n'y a aucune contrainte de programmation qui empêcherait d'
ls
être implémentée en tant que intégré, c'est-à-dire s'exécutant dans le même processus que l'interpréteur bash. Les raisons de conception pour lesquelles les commandes ne sont pas implémentées en tant que composants intégrés du shell sont les suivantes:Concernant la première raison - Vous voulez que le shell soit aussi indépendant et résilient que possible. Vous ne voulez pas que le shell
ls
reste bloqué sur un montage NFS qui "ne répond toujours pas".Concernant la deuxième raison - Dans de nombreux cas, vous souhaiterez peut-être utiliser un shell pour un système qui utilise Busybox ou un autre système de fichiers qui a une
ls
implémentation différente . Ou même utiliser la même source de shell dans les systèmes d'exploitation qui ont différentesls
implémentations.Concernant la troisième raison - Pour une expression telle que
find . -type d | xargs ls -lad
celle-ci il serait difficile voire impossible de l'implémenterls
dans le même processus que l'interpréteur shell.Concernant la quatrième raison - Certaines
ls
commandes peuvent prendre beaucoup de temps. Vous voudrez peut-être que le shell continue de faire autre chose en attendant.Remarque: Voir ce message utile de Warren Young en réponse à une question similaire.
la source
ls
dans un processus externe. Cela pourrait être fait, mais ce serait compliqué.bash
sortiealias | grep ls
. entréecat /etc/passwd | while read a; do echo "$a"; done
ls
ne nécessite pas de processus séparé. Très peu de commandes nécessitent en fait un processus distinct: seules celles qui doivent changer de privilèges.En règle générale, les shells implémentent des commandes en tant que commandes intégrées uniquement lorsque ces commandes doivent être implémentées en tant que commandes intégrées. Les commandes comme
alias
,cd
,exit
,export
,jobs
, ... besoin de lire ou de modifier un état interne de la coque, et ne peut donc pas être des programmes distincts. Les commandes qui n'ont pas de telles exigences peuvent être des commandes distinctes; de cette façon, ils peuvent être appelés à partir de n'importe quel shell ou autre programme.En regardant la liste des commandes intégrées dans bash, seules les commandes intégrées suivantes peuvent être implémentées en tant que commandes distinctes. Pour certains d'entre eux, il y aurait une légère perte de fonctionnalité.
command
- mais il perdrait son utilité dans des situations où il sePATH
peut qu'il ne soit pas configuré correctement et que le script l'utilisecommand
dans le cadre de sa configuration.echo
- c'est une fonction intégrée pour l'efficacité.help
- il pourrait utiliser une base de données distincte, mais l'incorporation du texte d'aide dans l'exécutable du shell a l'avantage de rendre l'exécutable du shell autonome.kill
- il y a deux avantages à avoir une fonction intégrée: elle peut reconnaître les désignations de tâches en plus des ID de processus, et elle peut être utilisée même lorsqu'il n'y a pas suffisamment de ressources pour démarrer un processus séparé.printf
- pour la même raison queecho
, et aussi pour supporter l'-v
option de mettre la sortie dans une variable.pwd
- la fonction intégrée offre la possibilité supplémentaire de suivre le répertoire courant logique (en laissant intacts les liens symboliques au lieu de les étendre).test
- c'est une fonction intégrée pour l'efficacité (et bash fait aussi de la magie avec les fichiers appelés/dev/fd/…
sur certains systèmes d'exploitation).Quelques obus offrent un nombre important de modules complémentaires supplémentaires. Il y a le châssis , qui est un shell conçu pour être un binaire autonome pour les réparations d'urgence (lorsque certaines commandes externes peuvent ne pas être utilisables). Il a un intégré
ls
, appelé-ls
, ainsi que d'autres outils tels que-grep
et-tar
. Les fonctions intégrées de Sash ont moins de capacités que les commandes à part entière. Zsh propose des fonctionnalités similaires dans son module zsh / files . Il n'en a pasls
, mais une extension générique (echo *
) etzstat
peut servir une fonction similaire.la source
Je pense que quelque chose que les gens manquent ici est la complexité de cisaillement du
ls
programme GNU sur Linux. La comparaison de la taille de l' exécutable dels
labash
et desdash
obus sur mon système Debian, nous voyons qu'il est assez grand:Inclure une version
ls
aussi complète que la version GNUbash
augmenterait la taille de l'exécutable de 10%. C'est presque la même taille que ladash
coque complète !La plupart des commandes internes du shell sont choisies parce qu'elles s'intègrent avec le shell d'une manière que les exécutables externes ne peuvent pas (la question souligne
cd
, mais un autre exemple est la version bash de l'kill
intégration avec le contrôle des tâches bash) ou parce que ce sont des commandes très simples à implémenter, donnant une grande vitesse vs gain de taille (true
etfalse
sont à peu près aussi simples que possible).GNU
ls
a eu un long cycle de développement et implémente plusieurs options pour personnaliser les résultats affichés. L'utilisation d'un ls intégré par défaut entraînerait la perte de cette fonctionnalité ou augmenterait considérablement la complexité et la taille du shell.la source
cd
est intégré au shell,ls
est un programme séparé que vous verrez sur/bin/ls
.la source
Faites ce que vous cherchez:
Vous pouvez également stocker les noms de fichiers dans un tableau:
Mais il ne se soucie pas des espaces dans les noms
Cela passe à variable et se soucie des espaces:
la source