W niektórych odpowiedziach, które zostały tutaj zarzucone, brakuje niektórych ważnych części tego, co sprawia, że demon jest demonem, w przeciwieństwie do samego procesu w tle lub procesu w tle odłączonego od powłoki.
Ten http://www.faqs.org/faqs/unix-faq/programmer/faq/ opisuje, co jest niezbędne, aby być demonem. I ten skrypt Run bash jako demon implementuje id seta, chociaż pomija chdir do roota.
Pytanie pierwotnego autora było w rzeczywistości bardziej szczegółowe niż „Jak utworzyć proces demona przy użyciu basha?”, Ale ponieważ temat i odpowiedzi omawiają generalnie skrypty powłoki demonizujące, myślę, że ważne jest, aby je wskazać (dla intruzów takich jak ja drobne szczegóły tworzenia demona).
Oto moja wersja skryptu powłoki, który zachowywałby się zgodnie z FAQ. Ustaw DEBUG, aby true
zobaczył ładny wynik (ale również kończy się natychmiast, zamiast zapętlać się w nieskończoność):
#!/bin/bash
DEBUG=false
trap process_USR1 SIGUSR1
process_USR1() {
echo 'Got signal USR1'
echo 'Did you notice that the signal was acted upon only after the sleep was done'
echo 'in the while loop? Interesting, yes? Yes.'
exit 0
}
print_debug() {
whatiam="$1"; tty="$2"
[[ "$tty" != "not a tty" ]] && {
echo "" >$tty
echo "$whatiam, PID $$" >$tty
ps -o pid,sess,pgid -p $$ >$tty
tty >$tty
}
}
me_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
me_FILE=$(basename $0)
cd /
if [ "$1" = "child" ] ; then
shift; tty="$1"; shift
$DEBUG && print_debug "*** CHILD, NEW SESSION, NEW PGID" "$tty"
umask 0
$me_DIR/$me_FILE XXrefork_daemonXX "$tty" "$@" </dev/null >/dev/null 2>/dev/null &
$DEBUG && [[ "$tty" != "not a tty" ]] && echo "CHILD OUT" >$tty
exit 0
fi
if [ "$1" != "XXrefork_daemonXX" ] ; then
tty=$(tty)
$DEBUG && print_debug "*** PARENT" "$tty"
setsid $me_DIR/$me_FILE child "$tty" "$@" &
$DEBUG && [[ "$tty" != "not a tty" ]] && echo "PARENT OUT" >$tty
exit 0
fi
exec >/tmp/outfile
exec 2>/tmp/errfile
exec 0</dev/null
shift; tty="$1"; shift
$DEBUG && print_debug "*** DAEMON" "$tty"
$DEBUG && [[ "$tty" != "not a tty" ]] && echo NOT A REAL DAEMON. NOT RUNNING WHILE LOOP. >$tty
$DEBUG || {
while true; do
echo "Change this loop, so this silly no-op goes away." >/dev/null
echo "Do something useful with your life, young padawan." >/dev/null
sleep 10
done
}
$DEBUG && [[ "$tty" != "not a tty" ]] && sleep 3 && echo "DAEMON OUT" >$tty
exit
Wynik wygląda tak, gdy DEBUG
jest ustawiony na true
. Zwróć uwagę, jak zmieniają się numery sesji i grup procesów (SESS, PGID):
<shell_prompt>$ bash blahd
*** PARENT, PID 5180
PID SESS PGID
5180 1708 5180
/dev/pts/6
PARENT OUT
<shell_prompt>$
*** CHILD, NEW SESSION, NEW PGID, PID 5188
PID SESS PGID
5188 5188 5188
not a tty
CHILD OUT
*** DAEMON, PID 5198
PID SESS PGID
5198 5188 5188
not a tty
NOT A REAL DAEMON. NOT RUNNING WHILE LOOP.
DAEMON OUT