Newsgroup: it.comp.os.linux.iniziare
Titolo: Creare un....demone  ;-)

Posta cosě forse puň sembrare strana...ma in effetti spesso si ha
a che fare con servizi che partono allo startup del tipo
rc.qualcosa start|stop|restart
Sono alle prese con la stesura di uno script bash e vorrei
che girasse come servizio dietro le quinte, senza ricorrere a
crond come faccio spesso.
Se č possibile stando cosě in termini generali, come posso fare
per dare questa forma allo script?
Dovrei fare uno script con la parte principale e poi gestirlo con
un secondo script che pensi lui a avviarlo mandandolo in background,
oppure stopparlo o riavviarlo?
O forse c'č qualche metodo piů furbo per impostare uno script
affinchč sia un demone, senza bisogno di appoggiarsi ad un
secondo programma?
Ho dato un'occhiata molto di sfuggita alla forma dei servizi
servizi in /etc/rc.d/.
Ma mi restano parecchi dubbi.
La domanda potrebbe essere un po' tecnica, ma confido nella
vostra esperienza.  ;-)
Saluti e a presto  :-P

 Saluti e a presto  :-P
PS.
Mi scuso di questa specie di multipost, ma probabilmente è una
domanda non prprio da icol.iniziare....cioè forse può stare bene
anche qua.
Al momento del primo post ho inviato senza pensarci troppo, ma
forse non ho meditato abbastanza sull'xpost...
Metto followup-to su entrambi i gruppi.
Saluti.

> vostra esperienza.  ;-)
Qual'č la domanda? Quali sono i dubbi?
Se dai un'occhiata meno di sfuggita agli script che ci sono in 
/etc/init.d o in /etc/rc.d dovresti averne di meno.

> vostra esperienza.  ;-)
Meglio se confidi in man bash
-- 
Flavio Visentin
Scientists have finally discovered what's wrong with the female brain:
On the left side, there is nothing right, and on the right side, there
is nothing left.

 per dare questa forma allo script?
Lo script lo crei e lo metti in /etc/init.d (guarda come sono fatti gli 
altri in quella cartella)
dopodiché con update-rc.d aggiorni i link nelle varie /etc/rc*
-- 
GenTLe ...di Varese, provincia.
La mia HP: 
http://digilander.iol.it/thegentle/index.htm
Questo è il mio backup. Ce ne sono tanti come lui, ma questo è il mio.
Il mio backup è il mio migliore amico, è la mia vita.

 Ma mi restano parecchi dubbi.
quali?

> servizi in /etc/rc.d/.
Se lo metti lě poi lo avvii e lo fermi come gli altri servizi e se muore 
resta morto. Se lo metti in /etc/inittab puoi specificare respawn e se 
muore il sistema lo riavvia.

 /etc/init.d o in /etc/rc.d dovresti averne di meno.
Il fatto è che quegli script prevedono (mi pare di capire) la gestione
di un eseguibile (il demone in questione...vedo sshd, ddclient
ecc ecc) "propriamente eseguibile", un binario di un programma scritto
in C solitamente...tanto per intenderci.
Nel mio caso avrei a che fare con un rc.bashdemone che dovrà
gestire appunto il mio "bash-daemon-script".
Sono giunto a questo modo di organizzare gli script grazie alle
risposte ottenute in questo thread....e sbirciando nella dir
/etc/rc.d della slackware.
A questo punto la domanda è, come deve essere fatto questo
demone in bash?
La domanda così è inevitabilmente troppo generica, penso sia il
caso di esporre più chiaramente cosa deve fare lo script...
Metto tutto in un altro post di questa stessa discussione. ;-)

 E' possibile farlo ma non è un metodo più furbo, anzi, un'inutile complicazione.
Bene, pare quindi che la via precedente sia migliore. Comunque ti
ringranzio anche per l'esempio successivo che non riporto...non
l'ho capito completamente, me lo riguarderò con più calma magari
col man bash di fianco  ;-)

 dopodiché con update-rc.d aggiorni i link nelle varie /etc/rc*
Ho scordato di evidenziare che sto usando slackware.
Direi anche che non voglio fare partire lo script
automaticamente. Vorrei farlo partire a mano cosě:
rc.myshdaemon start
e tanti saluti...

 quali?
Ora come ora riguardano non tanto il file di gestione
(rc.myshdaemon), quanto proprio lo script bash che funge da
demone.
Di solito si tratta di roba fatta i C, mentre demoni in
bash...bo non saprei.  :-\
Penso sia meglio chiarire cosa dovrebbe fare esattamente questo
script.
Mi serve per gestire un client bittorrent (transmissioncli)
sfruttando un tracker particolare presso cui è richiesta una
sorta di autenticazione.
L'autenticazione funziona attraverso l'iscrizione ad un sito.
In teoria si fa il login si scarica il torrent e lo si dà in pasto
a transmissioncli....
Ma mettiamo poi di chiudere il browser e perdere la connessione
col sito...bene in questo caso, transmission al successivo scarpe
del tracker inizia a darmi un'errore dicendo che devo accedere al
sito ed eseguire il login o registrarmi.
Seguendo le istruzioni e rimanendo loggati nel sito, l'errore in
transmission continua fino al successivo scrape.
Cambiando client le cose non cambiano. Il problema sta nel
meccanismo di "autenticazione" del tracker legato allo stato di
login presso il sito.
Con un po' di tests sono giunto alla conclusione che:
al login il sito associa il mio ip al mio utente.
Quando col client bittorrent mi collego al tracker, questo
confronta il mio ip con quello di login sul sito.
Se è lo stesso tutto OK, altrimenti transmission cli inizia a
restituire l'errore...
Non è un grosso problema direi, anche perchè pare scaricare
comunque, tuttavia vorrei far rientrare quell'errore. 
Sempre grazie ad alcuni test ho capito che lo stato di logged-in
presso il sito, viene garantito utilizzando i cookie del browser.
Cioè mettiamo di esserci loggati nel sito e aver avviato
transmissioncli. L'ip che vede il tracker è lo stesso che vede il
sito e non vi sono errori.
Ora mettiamo di sconnetterci da internet e riconnetterci...nel
mio caso avendo ip dinamico, ora ho un nuovo IP e quando
transmission esegue lo scrape, il tracker vede un ip diverso e
non mi riconosce più come utente registrato restituendomi errore:
a questo punto è sufficiente ricaricare una qualunque pagina del
sito (quindi grazie ai cookies non è più necessario rifare il
login) comunicando di conseguenza il mio nuovo IP al sito. E al
successivo scrape transmission cessa di lamentarsi.
L'obiettivo sarebbe quello di creare un demone in grado di:
0- memorizzare il mio attuale ip 
1- effettuare il login salvando i cookies
2- avviare transmissioncli
3- monitorare costantemente il mio ip
4- se il mio ip cambia:
 a- ricaricare una pagina del sito usando i cookies salvati
 b- inviare a transmissioncli il comando di scrape
Allora vediamo di chiarire qualche punto:
i punti 0 e 3 li ho realizzati filtrando con grep e sed, l'output
del comando ifconfig ppp0. Nel punto 3 si confronta il valore del
vecchio ip con quello attuale lavorando in un ciclo while
infinito e usando due variabili "ip" e "oldip".
per il punto 1 ho utilizzato wget grosso modo come segue:
wget --save-cookies $COOKIES --keep-session-cookies \
"
http://sito/login.php?username=myuser&password=mypasswd
"
per il punto 4.a:
wget --load-cookies $COOKIES --keep-session-cookies
"
http://sito/paginacaso.php
"
Probabilmente funziona anche aggiungendo l'opzione --spider a
wget in modo da non scaricare nient'altro che il file $COOKIES.
Ecco ora veniamo al controllo del client... punto 4-b
Semplicemente per ordinare a transmissioncli di aggiornare la
situazione del tracker, cioè eseguire lo scarpe basta inviargli
un segnale di SIGHUP:
kill -1 `pidof transmissioncli`
per esempio...
Per quanto riguarda l'avvio del client (2) se lo si usa dentro
uno script del genere è bene usare l'opzione "-o" che indica dove
salvare il file che si sta condividendo via bittorrent. Mentre
l'argomento del cmando è il file .torrent da utilizzare.
Mi piacerebbe impostare questi due valori:
/path/to/file.torrent
/path/to/saved.files.directory
...in un file di configurazione esterno allo script bash.
Infine veniamo ai log
In quanto demone sarebbe il caso di ottenere alcune info su ciò
che è accaduto e quando:
tutto l'output dello script dovrebbe ancdare in un file di log.
Mi farebbe comodo che di alcuni eventi venisse specificato il
tempo magari usando "date". Per esempio ogni qual volta il mio IP
cambia.
Poi sarebbe utile poter monitorare transmissioncli in tempo reale
quando mi serve: quindi avrei pensato a redirigerne l'output su
un file di testo per poi accedervi con un semplice "tail -f" per
esempio.
Ok, mi pare d'aver detto tutto...
Scusate la lunghezza, ma spero almeno di essere stato chiaro.
Qualsiasi commento, domanda, consiglio...sono sicuro che potrebbe
essermi utile.
Saluti e grazie di nuovo per le risposte già ricevute.  :-)

 Saluti e grazie di nuovo per le risposte già ricevute.  :-)
a me sembra che tu abbia le idee chiare su tutto :)

 a me sembra che tu abbia le idee chiare su tutto :)
Le apparenze...  ;-D
Diciamo che ho chiaro ciò che deve fare tutta la baracca, ma non
ho completamente capito il "come" di alcune operazioni, per esempio
redirigere adeguatamente gli output:
Se è un demone deve sputare tutto in  "> /dev/null 2>&1", tranne
però alcune info importanti quali quelle descritte sopra, che
vorrei averle in un file di log del tipo ~/.myshdaemon/msd.log.
Inoltre potrebbero esserci problemucci con l'output di
transmissioncli: la soluzione del file non l'ho testata molto,
più che altro è ancora un'idea.
Avevo pensato ad una dir nella home dell'utente con i seguenti
files:
~/.myshdaemon/
      msd.conf
      msd.log
      client.log
      cookies.txt
il primo è il file di configurazione, il secondo il log
principale, il terzo il log su cui redirigere l'output del client
bittorrent, nel nostro caso transmissioncli, ed infine il file
dei cookies che verrà aggiornato ad ogni login ed usato ad ogni
reload di una pagina del sito...penso nonmanchi nulla.
Se vi va di dire due parole sulla redirezione degli outout sono
tutt'orecchi  :-P

       cookies.txt
sì va bene, + l'err che ti ho detto sopra
 

JohnnyNewbie ha scritto:

Un pò incasinata la domanda, un pò incasinata la risposta...
Un demone tipo SSH è un applicazione che fa uso di socket e sta in 
ascolto su una porta in attesa di una connessione interna/esterna e 
mette a disposizione una serie di comandi ai quali esegue delle operazioni.
Quindi se vuoi un demone la soluzione più semplice è utilizzare Perl
cerca con google la parole magiche "perl socket"
Buon lavoro

 Buon lavoro
PSK

> Un p� incasinata la domanda, un p� incasinata la risposta...
Si evidentemente...  :-\
Rispondo ad entrambi.
Il fatto � che probabilmente un reale demone non mi serve per
l'obiettivo descritto.
Mi basta uno script bash silente capace di spedire output e error
su file di log. Quindi gestirlo con un secondo script del tipo di
qelli presenti in /etc/rc.d della slack.
Le vostre rispostee chiarimenti comunque rtestano e sono
sicuramente un punto di partenza pi� corretto per capire cosa sia
un demone e come fare a crearne uno.
Peccato che venga meno la possibilit� di usare bash...almeno da
parte mia (causa ignoranza) sarebbe stata una grossa
semplificazione, anche perch� di perl e python non ne so
praticamente nulla.
Mi hanno gi� consigliato di mettere mano alla documentazione,
visto che tendo a gestire diverse faccende del mio sistema
con degli script ad hoc, tuttavia avendo quasi sempre risolto
con bash, e per via del tempo e della voglia (lo ammetto), non mi
sono mai degnato di imparare seriamente altri e pi� potenti
linguaggi di scripting. :-/

 programmi e per comodità.
Ok, riprendo questa discussione che era rimasta un po' in
sospeso.
Condiderando il significato di demone, che come alcuni mi hanno
fatto notare non è un semplice job in background, ma ha alcune
caratteristiche aggiuntive ovvero sta in ascolto su una porta ecc
ecc.
Forse sarebbe il caso di cambiare il titolo del thread alla luce
di questo, ma va bè...spero che ci si capisca.
In sintesi vorrei semplicemente che uno script bash girasse in
background e allo stesso tempo poter uscire dalla bash che lo ha
lanciato senza che lo script muoia. Anche eventualmente
effettuando il logout vorrei che lo script restasse funzionante
in background.
In un caso del genere si potrebbe usare anche screen che
attraverso la possibilità di fare il detach della sessione
raggiunge lo scopo. Ma vorrei riuscire senza screen o nohup.
Ho quotato THe_ZipMAn che ne messaggio cui sto rispondendo aveva
inserito una soluzione contenente spunti interessanti.
Allora l'idea è quella di fare due script, il primo è uno script
di avvio/stop del secondo script che invece è appunto quello da
fare girare in background.
Riporto l'esempio in toto visto che è passato del tempo. Aggiungo
che l'esempio voleva essere un unico script che conteneva al suo
interno la sua "background/side". Come ho appena detto nei miei
tentativi, invece ho scelto la soluzione a due script distinti,
che lo stesso the_zipman consigliava.
Ok, vi riporto l'esempio (considerato inutile complicazione):

Ora vorrei proporvi la soluzione a due script.
-------------- demone.sh
#!/bin/bash
#
while [ 1 ]; do
  echo `date`>>data.log
  sleep 5
done
-----------------------
Il nostro demone è una cosa molto semplice, uno script che ogni 5
secondi scrive la data su un file di log.
Ora vediamo lo script che fa partire e ferma lo pseudo demone
precedente.
------------------------------------- rc.demone
#!/bin/bash
#
PIDFILE=./demone.lock
case "$1" in
  start)
       ./demone.sh &
       RET=$?
       echo $! > $PIDFILE
       disown %1
       exit $RET
  ;;
  stop)
      [ -f $PIDFILE ] && kill $( cat $PIDFILE )
      rm -f $PIDFILE
  ;;
  *)
   echo "Impara ad usarmi"
  ;;
esac
------------------------------------------------
Se non ho capito male il punto interessante di tutto questo
discorso sta nel comando builtin "disown".
Ammetto che dal man bash ho capito veramente poco, ma se non ho
capito male, dandogli in pasto un job della shell corrente,
dovrebbe evitare che chiudendo la shell venga terminato (sighup)
anche il job figlio. Con l'opzione -h inoltre il job resta
attaccato alla shell, quindi richiamabile dalla stessa (la shell
madre, non una a caso ovviamente) mentre senza quell'opzione
viene sganciato dalla shell che lo ha lanciato.
Insomma qualcosa di simile al detach di screen...ovviamente con
diverse lmitazioni, simile non uguale.
Ora, lo pseudo-demone in questione è molto semplice e non vi si
può interagire se non per faermarlo o farlo partire, ma
immaginando che uno pseudo demone del genere si basi su degli
input ricavati dalla lettura di opportuni file di testo, mi
sembra piuttosto semplice dedurre che modificando tali files di
testo, si potrebbe modificare a caldo il comportamento del
demone. In pratica sintetizzando:
1- uno script rc.qualcosa fa partire uno script in background
   grazie a disown chiamiamolo qualcosad.
2- qualcosad accede ricorsivamente a dei file di testo pe
   compiere operazioni sue.
3- si può creare un'interfaccia di comando per qualcosad agendo
   sui file di testo che usa come input.
Ovviamente il punto 3 è fumoso, generico e assolutamente non
applicato a qualcosa di concreto, me ne rendo conto. Ciò detto
però penso che quei tre punti possano essere interessanti per
creare e gestire diversi script "di sussistenza" che non
richiedono troppa interattività.
Ad esempio avevo in mente la creazione/modifica di uno script in
per la gestione dei download, capace di accedere ad una coda di
file da scaricare magari con wget, avere la possibilità di
fermare la coda, modificarla camiare l'ordine dei download,
impostavi liiti di velocità, golobale o spegifica ecc ecc.
Ci sta dietro un lavoro di interfaccia che non ho ancora bene in
mente. Ma il nocciolo del programma potrebbe essere uno pseudo
demone e quando si vuole monitorare e modificare la coda ecc, si
usa un'opportuna interfaccia. In questo modo si potrebbero
pensare anche più interfaccie magari basate su diverse soluzioni
testuali grafiche e basate su questa oquella libreria, tipo qt,
gtk ecc ecc magar tanto per restare in script bash, ricorrendo a
programmi come zenity.
Sarebbe interessante anche farlo lavorare tipo come amuled
potendovi accedere anche su una macchina remota, ma questo esula
dalle mie conoscenze e in quel caso si tratterebbe realmente di
un demone che sta in ascolto su una porta ecc ecc. Non penso che
si riuscirebbe a cavarsela con semplici script bash.

    sui file di testo che usa come input.
Per l'interfaccia di comando puoi sfruttare in modo proficuo i segnali.
Sempre su man bash puoi cercare il comando trap e usarlo per trappare i 
segnali HUP, USR1, USR2, ecc.ecc. Tipicamente HUP lo usi per far rileggere 
la configurazione, mentre USR1 e USR2 li usi per far compiere delle azioni.
dopo aver fatto questo con un semplice
kill -HUP `cat ./demone.lock`
per esempio riesci a far fare al demone delle operazioni pulite.
Trappando TERM per esempio puoi far eseguire delle operazioni alla chiusura 
del "demone" come 
p.es
. rimuovere il pidfile.


 chiusura del "demone" come 
p.es
. rimuovere il pidfile.
Ma, ecco prendiamo questo esempio: teoricamente quale sarebbe il
vantaggio di adottare il tarp del segnale TERM per eliminare il
file col pid piuttosto che aggiungerlo nel file di richiamo
rc.qualcosa?
Dici: meglio demandare ai programmi (potrebbero esserci più
pseudo-demoni in ballo) chiamati da rc.qualcosa la propria
"sessione di chiusura" lasciando il file rc.qualcosa il più
possibile sintetico e pulito?
Non sarebbe (e perchè) meglio adottare dei demoni "stupidi" e
localizzarne la gestione maggiormente nel file rc.qualcosa?
Ti ringrazio molto dell'intervento e del supporto, il mio esempio
(che poi pesca a piene mani nel tuo) allora non è un'idea
peregringrina...che ne pensi?
Intendo, soluzioni del genere in qualche anno di utilizzo di
linux ne ho viste poche e anche quando le ho cercate non ne ho
trovate di simili a questa, tutti indicano l'utilizzo di
programmi esterni come nohup o screen, quando invece se questa
soluzione è valida si farebbe solo ricorso al builtin di bash che
come idea non mi dispiace. Se ti va di aiutarmi ancora una volta
a capire questo aspetto sono tutto orecchi.  ;-)
Saluti e grazie di nuovo!  :-D

 a capire questo aspetto sono tutto orecchi.  ;-)
Ti posso fare un esempio del tuo programma con la gestione dei segnali.
Se per esempio avvi il demone con lo script e poi lo killi, non incorrerai 
nell'errore di demone in esecuzione.
-------------- demone.sh
#!/bin/bash
PIDFILE=/var/run/demone.sh.lock
[ -f "$PIDFILE" ] && echo "Gia' in esecuzione" && exit 1
echo $$ > $PIDFILE
LOG=/var/log/data.log
clean() {
    rm -f "$PIDFILE"
}
reload() {
    echo "Ho ricaricato alle ore `date '+%H:%M:%S'`" >>  $LOG
}
check_size() {
    echo "Il file di log è di `ls -l $LOG | awk '{print $5}'` bytes" >> $LOG
}
trap clean SIGTERM SIGINT SIGABRT EXIT
trap reload SIGHUP
trap check_size SIGUSR1
while [ 1 ]; do
   echo `date` >> $LOG
   sleep 5
done
-----------------------
------------------------------------- rc.demone
#!/bin/bash
#
PIDFILE=/var/run/demone.sh.lock
case "$1" in
   start)
        ./demone.sh &
        RET=$?
        disown %1
        exit $RET
   ;;
   stop)
       [ -f $PIDFILE ] && kill $( cat $PIDFILE )
   ;;
   *)
    echo "Impara ad usarmi"
   ;;
esac
------------------------------------------------
Rif. 
http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_12_02.html
e anche un man signal già che ci sei :)


 e anche un man signal già che ci sei :)
Ok, grazie ancora. Qualche dubbio ancora circa SIGUSR1/2, ma più
che altro nell'applcazione. Inutile parlarne ora, proverò appena
possso a scrivere lo script che avevo in mente ed eventualmente
mi rifaccio vivo. Mi stavo chiedendo se si potessero trappare
delle funzioni, ma mi hai anticipato con questa risposta e
l'esempio.
Grazie mille ancora di tutto. A presto!  :-D