Ejecutar el comando de correo desde una función provoca una "bomba tenedor"

8

Cuando intento ejecutar maildesde dentro una función en un script bash, crea algo similar a una bomba tenedor. Para aclarar, esto crea el problema:

#!/bin/bash

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

mail

exit 0

A veces puedes simplemente matar el comando y matará los procesos secundarios, pero a veces tendrás que hacerlo killall -9.

No le importa si el correo fue enviado o no. La bomba tenedor se crea de cualquier manera. Y no parece que agregar ninguna verificación para el código de salida, como if ! [ "$?" = 0 ], ayuda.

Pero el siguiente script funciona según lo previsto, ya sea que genera un error o envía el correo.

#!/bin/bash

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

exit 0

¿Por qué pasó esto? ¿Y cómo harías para verificar el código de salida del comando de correo?

roxto
fuente
10
Se llama recursividad.
Jakuje

Respuestas:

29

Estás invocando la función mail desde la misma función:

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

Esto debería funcionar:

#!/bin/bash

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

mailfunc

exit 0

Tenga en cuenta que el nombre de la función ya no se invoca desde dentro de la función misma.

Andrew Henle
fuente
3
Le pasa a lo mejor de nosotros, hombre.
Almo
15

De otra manera:

mail(){

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

... debería funcionar bien.

mikeserv
fuente
77
Tal vez enfatizando la commandparte, en cuanto al laico, es difícil notar ese cambio junto con el olly olly oxenfreey los 'and the rest' and@morecambios, especialmente con el resaltado de sintaxis.
wizzwizz4
1
@ wizzwizz4: apoyo este comentario.
mikeserv
1
Aunque es divertido ...
wizzwizz4
3

La solución más "tradicional" en estos casos es llamar al comando con la ruta completa:

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

Todas las demás respuestas funcionan y probablemente sean más portátiles, pero creo que esta es la solución más probable que encontraría en los scripts en el mundo real salvaje, por lo que la incluyo para completarla.

Orión
fuente
3
De hecho, no estoy acostumbrado a enviar correos electrónicos en / usr / bin.
Joshua
3
@Joshua, parece estar allí en OS X. En CentOS 6 está /bin/mail. Creo que esto demuestra el valor de la command mailsintaxis.
Comodín el
Arch Linux también tiene esto /usrporque su paradigma es mover todos los archivos binarios al mismo directorio, por lo que /bines solo un enlace simbólico /usr/bin. Entonces sí ... esto no es portátil, pero se ve más comúnmente que command, de alguna manera, especialmente en los scripts de arranque heredados que se hicieron específicamente para cada distribución, todas las rutas absolutas estaban codificadas (scripts rc en Slackware, por ejemplo).
orion