Précédent   Forum des professionnels en informatique > Systèmes > Linux > Applications > Shell
Shell Vos questions sur l'utilisation des commandes shell
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 17/02/2006, 10h53   #1
Membre du Club
 
Inscription : juin 2005
Messages : 255
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 255
Points : 43
Points : 43
Par défaut Quelle est cette commande qui plante linux?

Bonjour,


Comment marche cette commande qui fait planter le pinguoin: <<:(){ :|:&};:>>
(enlever le << et le >>).


Je l'ai testée sous fedora, le système se fige...


sincèrement
__________________
Je créer des sites web et je ne suis fan de voiture teintée et tout ce qui à trait au tuning: customisation, kit xenon, vitres teinté voiture et course automobile.
123quatre est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/02/2006, 11h05   #2
Membre Expert
 
Avatar de 2Eurocents
 
Inscription : septembre 2004
Messages : 2 180
Détails du profil
Informations personnelles :
Âge : 42

Informations forums :
Inscription : septembre 2004
Messages : 2 180
Points : 2 442
Points : 2 442
Vous seriez nantais, que je n'en serai pas surpris

Ce code :joue sur le fait que le shell (bash) accepte : comme nom valide pour une fonction. on peut le ré-écrire, de façon plus lisible, ainsi :
Code :
1
2
3
4
5
ma_fonction ()
{ 
  ma_fonction | ma_fonction&
}
ma_fonction
On définit ainsi une fonction récursive, dont la définition fait une première fois appel à elle même, pipée sur une seconde invocation, détachée en tâche de fond (donc dans un nouveau processus).

On lance ensuite cette fonction tueuse ...

Le système se fige alors rapidement à cause de la multiplication des forks qui en résulte ...
__________________
La FAQ Perl est par ici
: La fonction "Rechercher", on aurait dû la nommer "Retrouver" - essayez et vous verrez pourquoi !
2Eurocents est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/02/2006, 11h17   #3
Membre du Club
 
Inscription : juin 2005
Messages : 255
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 255
Points : 43
Points : 43
Ok.

merci pour la réponse !
123quatre est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/02/2006, 11h53   #4
Expert Confirmé
 
Avatar de Katyucha
 
Inscription : mars 2004
Messages : 3 109
Détails du profil
Informations personnelles :
Âge : 31
Localisation : Allemagne

Informations forums :
Inscription : mars 2004
Messages : 3 109
Points : 3 313
Points : 3 313
Ca fait planter tout système d'exploitation, pas seulement Linux.
C'est une boucle infinie...
Katyucha est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/02/2006, 11h55   #5
Membre du Club
 
Inscription : juin 2005
Messages : 255
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 255
Points : 43
Points : 43
Citation:
Ca fait planter tout système d'exploitation, pas seulement Linux.
C'est une boucle infinie...

merci pour ce rappel, j'oubliais que linux c'est QUE le noyau. (sourire)
123quatre est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/02/2006, 13h13   #6
Membre émérite
 
Avatar de Celelibi
 
Inscription : janvier 2004
Messages : 990
Détails du profil
Informations forums :
Inscription : janvier 2004
Messages : 990
Points : 822
Points : 822
Une simple fonction réccursive qui se rappel à l'infini ne provoquerait pas le même effet ?

Bash attend bien que la fonction ait fini de s'exécuté avant de piper le contenu non ? Et comme le premier appel ne rend pas la main, il n'y a aucun contenu pipé, donc le deuxième appel (celui juste après le pipe) n'est jamais exécuté.


Enfin voilà, des gens sont-ils capable d'expliquer précisément toutes les étapes avant le freez ?
__________________
Les vaches ne peuvent PAS voler, quoi qu'elles aient pu vous raconter.
Celelibi est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/02/2006, 15h12   #7
Membre Expert
 
Avatar de 2Eurocents
 
Inscription : septembre 2004
Messages : 2 180
Détails du profil
Informations personnelles :
Âge : 42

Informations forums :
Inscription : septembre 2004
Messages : 2 180
Points : 2 442
Points : 2 442
Citation:
Envoyé par Celelibi
Une simple fonction réccursive qui se rappel à l'infini ne provoquerait pas le même effet ?
Plus ou moins ... dans le cas présent, l'effet de la récursion est amplifié par la multiplication des processus liée au fork.

Citation:
Envoyé par Celelibi
Bash attend bien que la fonction ait fini de s'exécuté avant de piper le contenu non ?
Je ne le crois pas ... il suffit, pour s'en convaincre, de lancer un programme dont l'exécution est très longue et qui affiche des résultats de temps en temps. Si on le pipe sur less (ou more, pour les *vrais* unices), les données s'afficheront au fur et à mesure et less marquera une fin de page chaque fois qu'il aura assez de données. Il n'attendra pas la fin de l'exécution du programme.

Il y a donc bien exécution simultanée de ce qui est avant le pipe et de ce qui est après et en attends les données. La preuve par l'exemple :
Code :
{ for i in $( seq 1 120) ; do echo $i ; sleep 1; done } | less
Citation:
Envoyé par Celelibi
Et comme le premier appel ne rend pas la main, il n'y a aucun contenu pipé, donc le deuxième appel (celui juste après le pipe) n'est jamais exécuté.
Comme on vient de le voir, les deux appels sont exécutés, générant une cascade d'autres appels (un appel en provoque deux, qui en provoquent deux chacun, etc.)

A la dixième génération, on a déja 512 + 256 + 128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = 1023 appels simultanés, et ça double encore ...)

Citation:
Envoyé par Celelibi
Enfin voilà, des gens sont-ils capable d'expliquer précisément toutes les étapes avant le freez ?
A un moment ou à un autre, le système ne peut plus faire de nouveaux forks (limite du nombre de processus atteinte). Il n'est alors plus possible de lancer la moindre commande ...

A moins d'avoir, actif au préalable, un watchdog qui va flinguer ce qui pose problème, c'est le blocage.

La machine n'est plus récupérable, puis qu'il devient impossible de s'y connecter (plus de fork pour lancer de nouveaux shells) et les connexions déjà établies sont inutilisables (plus de fork pour lancer les commandes).


Je me demande (je n'ai pas voulu tester, j'ai besoin de ma machine ) s'il n'est pas possible d'éviter le phénomène en donnant de bonnes valeurs à ulimit (-u, -v et -p par exemple).
__________________
La FAQ Perl est par ici
: La fonction "Rechercher", on aurait dû la nommer "Retrouver" - essayez et vous verrez pourquoi !
2Eurocents est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/02/2006, 00h46   #8
Nouveau Membre du Club
 
Inscription : octobre 2004
Messages : 56
Détails du profil
Informations forums :
Inscription : octobre 2004
Messages : 56
Points : 33
Points : 33
tant qu'on est dans ce genre de question :
Citation:
Citation:
Envoyé par Celelibi
Une simple fonction réccursive qui se rappel à l'infini ne provoquerait pas le même effet ?

Plus ou moins ... dans le cas présent, l'effet de la récursion est amplifié par la multiplication des processus liée au fork.
la fonction recursive :
Code :
1
2
3
4
5
ma_fonction ()
{
  ma_fonction
}
ma_fonction
va a chaque appel consommer un soupson de memoire,
mais quand il n'y en aura plus, ne vas telle tout simplement pas planter, mourir et liberer la memoire utilisé ?
(j'ai pas trop envie de tester, la derniere fois j'ai du reinstaller le systeme avec des betises pareilles)
xlurp est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/02/2006, 09h25   #9
Membre émérite
 
Avatar de Celelibi
 
Inscription : janvier 2004
Messages : 990
Détails du profil
Informations forums :
Inscription : janvier 2004
Messages : 990
Points : 822
Points : 822
2Eurocents, comme l'a un peu dit xlurp, lorsque la limite de processus est atteinte, l'appel à la fonction devrait échouer et la fonction appellante devrait rendre la main et donc tout ça devrait "dérécursionner".

Si ce que j'ai dit s'avère vrai, il suffit de rajouter une boucle infinie
Code :
1
2
3
4
5
6
ma_fonction () {
  while [ 1 ]; do
    ma_fonction | ma_fonction &;
  done;
}
ma_fonction
Ne pas tenter à la maison ! ^^
__________________
Les vaches ne peuvent PAS voler, quoi qu'elles aient pu vous raconter.
Celelibi est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/02/2006, 09h55   #10
Membre émérite
 
Avatar de Pouic
 
Inscription : octobre 2004
Messages : 668
Détails du profil
Informations personnelles :
Âge : 28
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : octobre 2004
Messages : 668
Points : 904
Points : 904
Sous linux, ca freeze lamentablement car il n'y a pas de controle sur le nombre de processus : on rempli allegrement la table des process en mémoire, puis éventuellement on swap des process pour faire de la place et accueillir les (toujours) nouveau processus qui sont créés. Manque de pot, dans le tas, il y a des processus sytèmes "utiles" (scheduler, swapper), etc...
Là où ca devient dramatique, c'est lorsqu'un processus sytème "important" veut (doit) reprendre la main (un de ceux cités précédemment) : il est forcément sur le swap, puisqu'on a tout rempli avec la bombe fork : problème, il n'y a plus de place dans la table des processus pour permettre de dé-swapper le process en question... On attend donc qu'il y en ai un qui rende la main... Et comme ça n'arrive jamais, on freeze...

Par contre, sur un FreeBSD, il n'y a pas ce genre de problème, car le système conserve par devers tout une petite place dans la table des processus dédiée aux processus sytèmes : ceux-ci pourront donc toujours swapper... Donc sur un FreeBSD (j'ai testé pour vous ), ca ne freeze pas
__________________
Software becomes slower faster than hardware becomes faster

http://xrenault.developpez.com
API C standard (C ANSI )
Pouic est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/02/2006, 13h38   #11
Membre habitué
 
Inscription : décembre 2004
Messages : 129
Détails du profil
Informations forums :
Inscription : décembre 2004
Messages : 129
Points : 102
Points : 102
Avec cette commande on peut limiter le nombre de processus pour un utilisateur.
Rhineauféros est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/02/2006, 13h48   #12
Membre habitué
 
Inscription : décembre 2004
Messages : 129
Détails du profil
Informations forums :
Inscription : décembre 2004
Messages : 129
Points : 102
Points : 102
Citation:
Envoyé par Celelibi
Une simple fonction réccursive qui se rappel à l'infini ne provoquerait pas le même effet ?
Non, pas du tout car comme l'ordonnanceur n'est pas surchargé, le système arrivera toujours à donner la main aux autres processus ==> tu pourras donc tuer le processus gênant sans aucune difficulté.
Et quand il n'y aura plus assez de mémoire pour les appels récursifs, tu auras droit à une belle erreur de segmentation qui interrompra ton processus sans cause le moindre dégât au niveau du système.
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
$ vi toto.c
 
toto() {
 toto();
}
main() {
 toto();
}
:wq
 
$ make toto
$ ./toto
segmentation fault
Rhineauféros est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 23h27.


 
 
 
 
Partenaires

Hébergement Web