L'exécution d'une commande de messagerie à l'intérieur d'une fonction provoque une «bombe fourchette»

8

Lorsque j'essaie d'exécuter mailde l'intérieur d'une fonction dans un script bash, cela crée quelque chose de similaire à une bombe fork. Pour clarifier, cela crée le problème:

#!/bin/bash

mail() {
    echo "Free of oxens" | mail -s "Do you want to play chicken with the void?" "[email protected]"
}

mail

exit 0

Parfois, vous pouvez simplement tuer la commande et cela tuera les processus enfants, mais parfois vous devrez le faire killall -9.

Peu importe que le courrier ait été envoyé ou non. La bombe à fourche est créée de toute façon. Et il ne semble pas que l'ajout d'une vérification du code de sortie, tel que if ! [ "$?" = 0 ], aide.

Mais le script ci-dessous fonctionne comme prévu, soit il génère une erreur, soit il envoie le courrier.

#!/bin/bash

echo "Free of oxens" | mail -s "Do you want to play chicken with the void?" "[email protected]"

exit 0

Pourquoi cela arrive-t-il? Et comment procéder pour vérifier le code de sortie de la commande mail?

roxto
la source
10
Cela s'appelle la récursivité.
Jakuje

Réponses:

29

Vous appelez la fonction à mail partir de la même fonction:

#!/bin/bash

mail() {
    # This actually calls the "mail" function
    # and not the "mail" executable
    echo "Free of oxens" | mail -s "Do you want to play chicken with the void?" "[email protected]"
}


mail

exit 0

Cela devrait fonctionner:

#!/bin/bash

mailfunc() {
    echo "Free of oxens" | mail -s "Do you want to play chicken with the void?" "[email protected]"
}

mailfunc

exit 0

Notez que le nom de la fonction n'est plus appelé depuis la fonction elle-même.

Andrew Henle
la source
3
Ça arrive aux meilleurs d'entre nous, mec.
Almo
15

Autrement:

mail(){

    echo olly olly oxenfree | command mail -s 'and the rest' and@more
}

... devrait bien fonctionner.

mikeserv
la source
7
Soulignant peut-être la commandpartie, comme pour le profane, il est difficile de remarquer que le changement avec le olly olly oxenfreeet 'and the rest' and@morechange, en particulier avec la coloration syntaxique.
wizzwizz4
1
@ wizzwizz4 - Je soutiens ce commentaire.
mikeserv
1
Il est drôle mais ...
wizzwizz4
3

La solution la plus "traditionnelle" dans ces cas est en fait d'appeler la commande avec le chemin complet:

mail() {
    echo "Free of oxens" | /usr/bin/mail -s "Do you want to play chicken with the void?" "[email protected]"
}

Toutes les autres réponses fonctionnent et sont probablement plus portables, mais je pense que c'est la solution la plus probable que vous trouveriez dans les scripts dans le monde réel sauvage, donc je l'inclus pour être complet.

orion
la source
3
En effet, je n'ai pas l'habitude d'envoyer des e-mails dans / usr / bin.
Joshua
3
@Joshua, il semble être là sur OS X. Dans CentOS 6, c'est /bin/mail. Je pense que cela prouve la valeur de la command mailsyntaxe.
Wildcard
Arch Linux a également cela /usrparce que leur paradigme est de déplacer tous les binaires dans le même répertoire, donc /binc'est juste un lien symbolique vers /usr/bin. Alors oui ... ce n'est pas portable, mais c'est plus courant que command, d'une manière ou d'une autre - en particulier dans les scripts de démarrage hérités qui ont été créés spécifiquement pour chaque distribution, tous les chemins absolus étaient codés en dur (scripts rc dans Slackware, par exemple).
orion