Выполнение команды mail изнутри функции вызывает «бомбу разветвления»

8

Когда я пытаюсь выполнить mailфункцию изнутри скрипта bash, она создает нечто похожее на бомбу-вилку. Чтобы уточнить, это создает проблему:

#!/bin/bash

mail() {
    echo "Free of oxens" | mail -s "Do you want to play chicken with the void?" "example@example.org"
}

mail

exit 0

Иногда вы можете просто убить команду, и она убьет дочерние процессы, но иногда вам придется killall -9.

Неважно, было ли отправлено письмо или нет. Вилка бомба создана так или иначе. И это не похоже на добавление какой-либо проверки кода завершения, например if ! [ "$?" = 0 ], подсказок.

Но приведенный ниже скрипт работает как задумано, либо выдает ошибку, либо отправляет почту.

#!/bin/bash

echo "Free of oxens" | mail -s "Do you want to play chicken with the void?" "example@example.org"

exit 0

Почему это происходит? И как бы вы проверили код выхода команды mail?

roxto
источник
10
Это называется рекурсия.
Jakuje

Ответы:

29

Вы вызываете функцию mail из той же функции:

#!/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?" "example@example.org"
}


mail

exit 0

Это должно работать:

#!/bin/bash

mailfunc() {
    echo "Free of oxens" | mail -s "Do you want to play chicken with the void?" "example@example.org"
}

mailfunc

exit 0

Обратите внимание, что имя функции больше не вызывается из самой функции.

Эндрю Хенле
источник
3
Случается с лучшими из нас, чувак.
Almo
15

В противном случае:

mail(){

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

... должно работать нормально.

mikeserv
источник
7
Возможно , подчеркивая commandроль, как и для непрофессионала это трудно заметить , что изменение наряду с olly olly oxenfreeи 'and the rest' and@moreизменениями, особенно с подсветкой синтаксиса.
wizzwizz4
1
@ wizzwizz4 - я поддерживаю этот комментарий.
mikeserv
1
Это является смешно , хотя ...
wizzwizz4
3

Наиболее «традиционным» решением в этих случаях является вызов команды с полным путем:

mail() {
    echo "Free of oxens" | /usr/bin/mail -s "Do you want to play chicken with the void?" "example@example.org"
}

Все остальные ответы работают и, вероятно, более переносимы, но я думаю, что это наиболее вероятное решение, которое вы найдете в сценариях в диком реальном мире, поэтому я включил его для полноты.

Орион
источник
3
На самом деле я не привык, чтобы почта находилась в / usr / bin.
Джошуа
3
@ Иисус Навин, кажется, что там на OS X. В CentOS 6 это /bin/mail. Я думаю, что это доказывает ценность command mailсинтаксиса.
Wildcard
Arch Linux также имеет это, /usrпотому что их парадигма заключается в перемещении всех двоичных файлов в один и тот же каталог, так что /binэто просто символическая ссылка на /usr/bin. Так что да ... это не переносимо, но чаще встречается, чем- commandто - особенно в старых загрузочных скриптах, которые создавались специально для каждого дистрибутива, все абсолютные пути были жестко закодированы (например, скрипты rc в Slackware).
Орион