Das Ausführen eines Mail-Befehls innerhalb einer Funktion verursacht eine „Gabelbombe“.

8

Wenn ich versuche, maileine Funktion in einem Bash-Skript auszuführen , entsteht etwas Ähnliches wie eine Gabelbombe. Zur Verdeutlichung entsteht dadurch das Problem:

#!/bin/bash

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

mail

exit 0

Manchmal können Sie den Befehl einfach beenden und die untergeordneten Prozesse werden beendet, aber manchmal müssen Sie dies tun killall -9.

Es ist egal, ob die Mail gesendet wurde oder nicht. Die Gabelbombe wird so oder so erzeugt. Und es scheint nicht hilfreich zu sein, den Exit-Code zu überprüfen if ! [ "$?" = 0 ].

Das folgende Skript funktioniert jedoch wie beabsichtigt. Entweder gibt es einen Fehler aus oder es sendet die E-Mail.

#!/bin/bash

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

exit 0

Warum passiert das? Und wie würden Sie den Exit-Code des Mail-Befehls überprüfen?

roxto
quelle
10
Es heißt Rekursion.
Jakuje

Antworten:

29

Sie rufen die Funktion mail innerhalb derselben Funktion auf:

#!/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

Das sollte funktionieren:

#!/bin/bash

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

mailfunc

exit 0

Beachten Sie, dass der Funktionsname nicht mehr innerhalb der Funktion selbst aufgerufen wird.

Andrew Henle
quelle
3
Passiert den Besten von uns, Mann.
Almo
15

Andernfalls:

mail(){

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

... sollte gut funktionieren.

mikeserv
quelle
7
Vielleicht wird der commandTeil betont , und für den Laien ist es schwer zu bemerken, dass sich diese Änderung zusammen mit der olly olly oxenfreeund 'and the rest' and@moreändert, insbesondere mit der Syntaxhervorhebung.
wizzwizz4
1
@ wizzwizz4 - Ich unterstütze diesen Kommentar.
Mikeserv
1
Es ist aber lustig ...
wizzwizz4
3

Die "traditionellste" Lösung in diesen Fällen besteht darin, den Befehl mit vollständigem Pfad aufzurufen:

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

Alle anderen Antworten funktionieren und sind wahrscheinlich portabler, aber ich denke, dass dies die wahrscheinlichste Lösung ist, die Sie in Skripten in der wilden realen Welt finden würden. Der Vollständigkeit halber füge ich sie daher hinzu.

Orion
quelle
3
In der Tat bin ich es nicht gewohnt, in / usr / bin zu mailen.
Joshua
3
@ Joshua, es scheint unter OS X vorhanden zu sein. In CentOS 6 ist es /bin/mail. Ich denke, das beweist den Wert der command mailSyntax.
Wildcard
Arch Linux hat dies auch, /usrweil ihr Paradigma darin besteht, alle Binärdateien in dasselbe Verzeichnis zu verschieben, also /binnur ein Symlink zu /usr/bin. Also ja ... das ist nicht portabel, aber es wird häufiger gesehen als commandirgendwie - insbesondere in älteren Boot-Skripten, die speziell für jede Distribution erstellt wurden, wurden alle absoluten Pfade fest codiert (z. B. RC-Skripte in Slackware).
Orion