Eu escrevi o script de shell abaixo para um laboratório na minha faculdade. Ele deve examinar um arquivo de log sendo atualizado com freqüência de outro processo e criar várias cópias aprovadas no invokation.
Aqui está o código ( logrotate.sh ):
#!/bin/bash
# Usage:
# logrotate.sh [-n int] [-s signal] logfile
# where:
# int is an optional integer used to make int number of copies of logfile
# signal is the name of signal which shell command fuser must send to the process managing logfile
# this script lacks of a strong parameters checking
NCOPIES=4
LOGSIGNAL=USR1
#use of getopts to parse the arguments
while getopts "n:s:" OPTION ; do
case $OPTION in
n) NCOPIES="$OPTARG"
;;
s) LOGSIGNAL="$OPTARG"
;;
?) printf "Usage: %s [-n copies to keep] [-s signal to send] filename\n" $(basename $0) >&2
exit 1
;;
esac
done
#shift to read the last parameter (logfile)
shift $(($OPTIND - 1))
LOGFILE=$1
#create logfile.2 logfile.3 ... logfile.NCOPIES
for i in 'seq $NCOPIES -1 1' ; do
test -f $LOGFILE.$i && mv $LOGFILE.$i $LOGFILE.$[ $i + 1 ]
done
mv $LOGFILE $LOGFILE.1
#sending signal to process which is writing to logfile to keep on writing to $LOGFILE(original name, without any extensions)
fuser -k -"$LOGSIGNAL" $LOGFILE.1
Então eu escrevi dois scripts que cada segundo escreve no arquivo log :
-o programa C ( logtest.c ):
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
int fd = open("log", O_WRONLY | O_APPEND);
if(fd < 0 ){
printf("Impossible to open file %s.\n", "log");
return -1;
}
for(;;){
if(write(fd, "Ciao bello mio\n", 15) != 15){
write(2, "Error in writing data.\n", 23);
}
sleep(1);
}
close(fd);
exit(0);
}
- e o script de shell ( logtest.sh ):
#! /bin/bash
while true
do
echo $(date) >> log
sleep 1
done
Quando eu inicio
./logtest.sh &
./logrotate.sh log
o script logrotate.sh move todos os arquivos com os nomes corretos ( log torna-se log.1 ) e envia o sinal para o processo que possui o arquivo log para aquele momento (então o script de shell logtest.sh ) que então continua escrevendo no arquivo log . Além disso, parece que não há diferença sobre qual sinal eu envio com o fusor: ele irá reagir sempre da mesma maneira.
No entanto, se eu iniciar
./logtest &
./logrotate.sh log
acontece que o programa C logtest recebe o sinal do comando fuser e termina.
Minha pergunta é: por que os dois programas de registro têm reações diferentes ao sinal enviado pelo fusor? Quer dizer, porque o script schell continua funcionando, enquanto o programa C termina?
Na página man do fusor, na seção RESTRICTIONS, ele diz
The -k option only works on processes.
Será que os scripts de shell não são considerados processos reais no shell? Isso seria novo para mim ... Eu procurei na Internet, mas nenhuma página encontrada sobre o fuser entra profundamente na seção de sinalização.