Quelles sont les valeurs min et max des codes de sortie suivants sous Linux:
- Le code de sortie renvoyé par un exécutable binaire (par exemple: un programme C).
- Le code de sortie renvoyé par un script bash (lors de l'appel
exit
). - Le code de sortie renvoyé par une fonction (lors de l'appel
return
). Je pense que c'est entre0
et255
.
linux
executable
function
exit-status
utilisateur271801
la source
la source
return
Est, bien sûr, un shell intégré.bash
shell. Certains autres shells, par exemple,zsh
peuvent renvoyer n'importe quelle valeur 32 bits signée, comme pourexit
. Certains aimentrc
oues
peuvent renvoyer des données de n'importe quel type pris en charge (scalaire ou liste). Voir le Q & A lié pour plus de détails.Réponses:
Numéro transmis à l' appel système
_exit()
/exit_group()
(parfois appelé code de sortie pour éviter toute ambiguïté avec l' état de sortie, qui fait également référence à un codage du code de sortie ou du numéro de signal et d'informations supplémentaires, selon que le processus a été arrêté ou arrêté normalement. ) est de typeint
, donc sur les systèmes de type Unix tels que Linux, généralement un entier 32 bits avec des valeurs comprises entre -2147483648 (-2 31 ) et 2147483647 (2 31 -1).Cependant, sur tous les systèmes, lorsque le processus parent (ou le subreaper des enfants ou
init
si le parent est mort) utilise leswait()
,waitpid()
,wait3()
,wait4()
appels système pour le récupérer, seuls les 8 bits inférieurs de celui - ci sont disponibles (valeurs 0 à 255 (2 8 - 1)).Lors de l'utilisation de l'
waitid()
API (ou d'un gestionnaire de signal sur SIGCHLD), sur la plupart des systèmes (et comme POSIX l'exige maintenant plus clairement dans l'édition 2016 de la norme (voir_exit()
spécification )), le numéro complet est disponible (dans lesi_status
champ de la structure renvoyée). ). Ce n’est pas encore le cas sous Linux, qui tronque également le nombre à 8 bits avec l’waitid()
API, bien que cela puisse changer à l’avenir.En règle générale, vous ne souhaitez utiliser que les valeurs comprises entre 0 (généralement synonyme de succès) et 125 uniquement, car de nombreux shells utilisent des valeurs supérieures à 128 dans leur
$?
représentation de l' état de sortie pour coder le numéro de signal d'un processus en cours de suppression et 126 et 127 pour des opérations spéciales. conditions.Vous voudrez peut-être utiliser entre 126 et 255
exit()
pour signifier la même chose que pour le shell$?
(comme lorsqu'un script le faitret=$?; ...; exit "$ret"
). L'utilisation de valeurs autres que 0 -> 255 n'est généralement pas utile. Vous ne le ferez généralement que si vous savez que le parent utilisera l'waitid()
API sur des systèmes qui ne tronquent pas et que vous avez besoin de la plage de valeurs 32 bits. Notez que si vous faites unexit(2048)
exemple, cela sera vu comme un succès par les parents utilisant leswait*()
API traditionnelles .Plus d'infos sur:
J'espère que cette question-réponse devrait répondre à la plupart de vos autres questions et clarifier ce que l'on entend par statut de sortie . J'ajouterai quelques petites choses:
Un processus ne peut pas se terminer s'il n'est pas tué ou s'il appelle les appels
_exit()
/exit_group()
system. Lorsque vous revenez demain()
dansC
, les appels libc appel système avec la valeur de retour.La plupart des langues ont une
exit()
fonction qui encapsule cet appel système et la valeur qu'elles prennent, le cas échéant, est généralement passée telle quelle à l'appel système. (notez que ceux-ci font généralement plus de choses comme le nettoyage effectué par laexit()
fonction de C qui vide les tampons stdio, exécute lesatexit()
crochets ...)C'est le cas d'au moins:
Vous en voyez parfois qui se plaignent lorsque vous utilisez une valeur en dehors de 0-255:
Certains coquillages se plaignent lorsque vous utilisez une valeur négative:
POSIX laisse le comportement indéfini si la valeur transmise à la commande
exit
spéciale spéciale est en dehors de 0-> 255.Certains coquillages présentent des comportements inattendus:
bash
(etmksh
mais paspdksh
sur lequel il est basé) se charge de tronquer la valeur à 8 bits:Donc, dans ces shells, si vous voulez sortir avec une valeur en dehors de 0-255, vous devez faire quelque chose comme:
C'est exécuter une autre commande dans le même processus qui peut appeler l'appel système avec la valeur souhaitée.
comme mentionné dans cet autre Q & A,
ksh93
a le comportement le plus étrange pour les valeurs de sortie de 257 à 256 + max_signal_number où au lieu d'appelerexit_group()
, il se tue avec le signal correspondant¹.et sinon, tronque le nombre comme
bash
/mksh
.¹ Cela risque toutefois de changer dans la prochaine version. Maintenant que le développement de
ksh93
a été repris en tant qu'effort communautaire en dehors d'AT & T, ce comportement, même s'il a été encouragé par POSIX, est en train d'être annulé.la source
si_status
Linux?int
au moins 16 bits, POSIX exige au moins 32 bits et les environnements de programmation un uint32_t . Je ne sais pas si Linux prend en charge un environnement de programmation où les entrées sont tout sauf 32 bits, je n'en ai jamais rencontré.Le minimum est
0
, et c'est considéré la valeur de succès. Tous les autres sont des échecs. Le maximum est255
également appelé-1
.Ces règles s'appliquent à la fois aux scripts et aux autres exécutables, ainsi qu'aux fonctions du shell.
Des valeurs plus grandes résultent en modulo 256.
la source
bash
ou d'autres plus couramment utilisés), le code de sortie transmis à la commandeexit
intégrée n'est pas traité comme modulo-256, mais provoque plutôt une erreur. (Par exemple, le communexit -1
n’est en réalité pas un équivalent portableexit 255
dans la plupart des coques). Et siexit(-1)
le niveau C est équivalent àexit(255)
un détail dont le fonctionnement est de facto certain, mais qui repose sur un comportement défini par la mise en œuvre (bien que cela ne soit pas un problème sur les systèmes modernes, vous pourrez probablement l'utiliser en pratique).exit(1)
paramètre à 8 bits.Cela a l'air si simple, mais oh les malheurs.
Le langage C (et suivant la plupart des autres langages directement ou indirectement) exige que le renvoi de
main
soit équivalent à un appelexit
avec le même argument que la valeur de retour. Ceci est un entier (le type de retour est très clairint
), donc en principe, la plage seraitINT_MIN
toINT_MAX
.Cependant, POSIX précise que seuls les 8 bits les plus bas passés
exit
doivent être mis à la disposition d'un processus parent en attente, littéralement comme s'il s'agissait de "status & 0xFF" .Ainsi, en pratique, le code de sortie est un entier (encore signé) dont seuls les 8 bits les plus bas sont définis.
Le minimum sera donc de -128 et le maximum de 127. Accrochez-vous, ce n'est pas vrai. Ce sera 0 à 255.Mais hélas, bien sûr, cela ne peut pas être aussi simple . En pratique, Linux (ou plutôt bash) le fait différemment . La plage de codes retour valide est comprise entre 0 et 255 (c.-à-d. Non signé).
Pour éviter toute confusion, il est probablement judicieux de supposer que les codes de retour ne sont pas signés et de renvoyer tout ce que vous renvoyez
wait
en non signé. De cette façon, cela correspond à ce que vous voyez dans un shell. Etant donné que les bits les plus hauts (y compris le plus significatif) sont effacés, ce n'est même pas "faux" car, bien que techniquement signés, les valeurs réelles sont toujours non signées (car le bit de signe n'est jamais défini).Cela permet également d'éviter l'erreur courante de comparer un code de sortie à
-1
, qui pour une raison étrange ne semble jamais apparaître même lorsqu'un programme se termine avec-1
(eh bien, devinez pourquoi!).A propos de votre dernier point, en revenant d’une fonction, si cette fonction se trouve être
main
, voir ci-dessus. Sinon, cela dépend du type de retour de la fonction, il pourrait en principe être n'importe quoi (y comprisvoid
).la source
waitid()
son introduction.waitid()
fait exactement la même chose, légèrement différemment. Il attend un identifiant particulier ou un fil, et écrit les résultats dans lasiginfo_t
structure pointée vers oùsi_status
estint
(donc ... signé , de la même manière). Resteexit()
que ne passe que les 8 bits les plus bas, donc ... absolument la même chose sous le capot.exit()
transmet tous les 32 bits du paramètre au noyau etwaitid()
renvoie tous les 32 bits du code de sortie. Peut-être avez-vous vérifié sur Linux où personne ne se soucie de corriger les bogues. Si vous ne me croyez pas, vérifiez-le sur un système d'exploitation compatible POSIX ...exit
, en particulier la deuxième ligne sous "Description" qui indique: "bien que seuls les 8 bits les moins significatifs (c'est-à-dire, statut & 0377) soient disponibles pour un processus parent en attente " . C’est ainsi qu’une implémentation conforme fonctionne: 8 bits au plus bas, et non 32. Avez-vous une référence pour 32 bits transmis?waitid()
et lasiginfo_t
structure transmise auSIGCHLD
gestionnaire. tous les 32 bits duexit()
paramètre.Les codes de sortie de tout processus (qu’il s’agisse d’un exécutable binaire, d’un script shell ou de tout autre procédé) vont de 0 à 255. Il est possible de passer une valeur plus grande à
exit()
, mais seuls les 8 bits les plus bas de l’état sont rendus disponibles. d'autres processus à traverswait()
.La fonction AC peut être déclarée comme renvoyant presque n'importe quel type. Les limites de sa valeur de retour sont entièrement déterminées par ce type: par exemple, -128 à 127 pour une fonction renvoyée
signed char
, 0 à 4,2 milliards pour une fonction renvoyéeunsigned int
, ou tout nombre à virgule flottante allant jusqu'à et y comprisinf
pour une fonction renvoyéedouble
. Et cela ne compte pas les types non numériques, commevoid *
ou unstruct
...la source