Executar comando de correio de dentro de uma função causa uma "bomba de forquilha"

8

Quando tento executar mailde dentro de uma função em um script bash, ele cria algo semelhante a uma fork fork. Para esclarecer, isso cria o problema:

#!/bin/bash

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

mail

exit 0

Às vezes você pode simplesmente matar o comando e isso mata os processos filhos, mas às vezes você precisa killall -9.

Não importa se o email foi enviado ou não. A bomba dos garfos é criada de qualquer maneira. E não parece adicionar nenhuma verificação do código de saída, como if ! [ "$?" = 0 ]ajuda.

Mas o script abaixo funciona conforme o esperado, ou gera um erro ou envia o email.

#!/bin/bash

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

exit 0

Por que isso acontece? E como você verificaria o código de saída do comando mail?

roxto
fonte
10
Isso é chamado de recursão.
Jakuje

Respostas:

29

Você está invocando a função mail de dentro da mesma função:

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

Isso deve funcionar:

#!/bin/bash

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

mailfunc

exit 0

Observe que o nome da função não é mais chamado de dentro da própria função.

Andrew Henle
fonte
3
Acontece com o melhor de nós, cara.
Almo
15

De outra forma:

mail(){

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

... deve funcionar bem.

mikeserv
fonte
7
Talvez enfatizando a commandparte, como para o leigo é difícil perceber que as mudanças mudam junto com olly olly oxenfreee 'and the rest' and@more, especialmente com o destaque da sintaxe.
precisa saber é o seguinte
1
@ wizzwizz4 - Apoio este comentário.
mikeserv
1
Ele é que engraçado ...
wizzwizz4
3

A solução mais "tradicional" nesses casos é realmente chamar o comando com o caminho completo:

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

Todas as outras respostas funcionam e provavelmente são mais portáteis, mas acho que essa é a solução mais provável que você encontraria em scripts no mundo real; portanto, incluo-a por completo.

orion
fonte
3
Na verdade, eu não estou acostumado a enviar emails para / usr / bin.
Joshua Joshua
3
@ Josué, parece estar lá no OS X. No CentOS 6 é /bin/mail. Eu acho que isso prova o valor da command mailsintaxe.
Curinga
O Arch Linux também possui isso /usrporque seu paradigma é mover todos os binários para o mesmo diretório, portanto, /biné apenas um link simbólico para /usr/bin. Então sim ... isso não é portátil, mas é mais comum do que command, de alguma forma - especialmente em scripts de inicialização herdados que foram criados especificamente para cada distribuição, todos os caminhos absolutos foram codificados (scripts rc no Slackware, por exemplo).
orion 21/01