Menjalankan perintah email dari dalam suatu fungsi menyebabkan "bom fork"

8

Ketika saya mencoba mengeksekusi maildari dalam suatu fungsi dalam skrip bash, ia menciptakan sesuatu yang mirip dengan bom fork. Untuk memperjelas, ini menciptakan masalah:

#!/bin/bash

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

mail

exit 0

Kadang-kadang Anda hanya bisa membunuh perintah dan itu akan membunuh proses anak, tetapi kadang-kadang Anda harus melakukannya killall -9.

Tidak peduli apakah surat itu dikirim atau tidak. The bom garpu dibuat dengan cara baik. Dan sepertinya tidak menambahkan cek untuk kode keluar, seperti if ! [ "$?" = 0 ], membantu.

Tetapi skrip di bawah ini berfungsi sebagaimana dimaksud, baik itu menghasilkan kesalahan atau mengirim surat.

#!/bin/bash

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

exit 0

Mengapa ini terjadi? Dan bagaimana Anda akan memeriksa kode keluar dari perintah email?

roxto
sumber
10
Ini disebut rekursi.
Jakuje

Jawaban:

29

Anda memohon fungsi mail dari dalam fungsi yang sama:

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

Ini seharusnya bekerja:

#!/bin/bash

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

mailfunc

exit 0

Perhatikan bahwa nama fungsi tidak lagi dipanggil dari dalam fungsi itu sendiri.

Andrew Henle
sumber
3
Terjadi pada yang terbaik dari kita, teman.
Almo
15

Jika tidak:

mail(){

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

... harus bekerja dengan baik.

mikeserv
sumber
7
Mungkin menekankan commandbagian itu, seperti untuk orang awam, sulit untuk memperhatikan bahwa perubahan seiring dengan olly olly oxenfreedan 'and the rest' and@moreperubahan, terutama dengan penyorotan sintaksis.
wizzwizz4
1
@ wizzwizz4 - Saya mendukung komentar ini.
mikeserv
1
Ini adalah meskipun lucu ...
wizzwizz4
3

Solusi paling "tradisional" dalam kasus ini adalah dengan memanggil perintah dengan path lengkap:

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

Semua jawaban lain berfungsi, dan mungkin lebih portabel, tetapi saya pikir ini adalah solusi yang paling mungkin Anda temukan dalam skrip di dunia nyata yang liar, jadi saya memasukkannya untuk kelengkapan.

orion
sumber
3
Memang saya tidak terbiasa dengan mail yang berada di / usr / bin.
Yosua
3
@ Yosua, sepertinya ada di OS X. Di CentOS 6 itu /bin/mail. Saya pikir ini membuktikan nilai command mailsintaks.
Wildcard
Arch Linux juga memiliki ini /usrkarena paradigma mereka adalah untuk memindahkan semua binari ke direktori yang sama, jadi /binhanya sebuah symlink ke /usr/bin. Jadi ya ... ini tidak portabel, tetapi lebih umum dilihat daripada command, entah bagaimana - terutama dalam skrip boot lawas yang dibuat khusus untuk setiap distribusi, semua jalur absolut di-hardcode (skrip rc di Slackware, misalnya).
orion