Различие между программами C и сценариями оболочки, получающими сигналы от термофиксатора

Я записал сценарий оболочки ниже для лаборатории в моем колледже. Это должно посмотреть на файл журнала, обновляемый часто от другого процесса, и создать много копий, переданных при вызове. Вот код (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  

Таким образом, я записал два сценария, которые каждая вторая запись в файл зарегистрируйтесь:
- программа 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);  
}  

- и сценарий оболочки (logtest.sh):

#! /bin/bash  

while true 
do
    echo $(date) >> log
    sleep 1
done  

Когда я запускаюсь

./logtest.sh и
Журнал./logrotate.sh

сценарий logrotate.sh перемещает все файлы с корректными именами (журнал становится журналом 1), и отправьте сигнал в процесс, который владеет журналом файла в течение того момента (так сценарий оболочки logtest.sh), который затем продолжает писать на журнале файла. Кроме того, кажется, что нет никакого различия, о котором сигнале я отправляю с термофиксатором: это будет всегда реагировать тот же путь.

Однако, если я запускаюсь

./logtest и
Журнал./logrotate.sh

это происходит, что программа C logtest получает сигнал от термофиксатора команды и затем завершается.

Мой вопрос: почему две программы входа имеют различные реакции на сигнал, отправленный от термофиксатора? Я имею в виду, почему сценарий оболочки продолжает работать, пока программа C завершается?

В странице справочника термофиксатора в разделе RESTRICTIONS это говорит

-k опция только работает над процессами.

Могло случиться так, что сценарии оболочки не рассматривают как реальные процессы в оболочке? Это было бы новым для меня... Я искал в Интернете, но никакая страница, найденная о термофиксаторе, не идет глубоко в сигнальном разделе.

0
задан 27 May 2015 в 02:41

2 ответа

Проблема состоит в том, что fuser только работы над процессами в настоящее время с помощью файла, которые имеют открытый дескриптор файла для них в ядре.

, В то время как это верно для Вашего C программа, это не верно для Вашего bash сценарий:

echo $(date) >> log

Просто открывает файл, добавляет stdout к нему и сразу закрывает его. Таким образом, файл никогда не считают, как открыто ядром на fuser проверка.

простое решение А должно было бы изменить Ваш bash сценарий так, чтобы файл это сохранило открытым до while концы цикла:

#! /bin/bash  

while true 
do
    echo $(date) >> log
    sleep 1
done < log

Этот способ, которым дескриптор файла для log создается на while, запуск цикла и он сохранил открытым до while конец цикла.

0
ответ дан 27 May 2015 в 02:41

Ваш сценарий logtest.sh действительно только вписывает log и сразу закрывает дескриптор файла. Таким образом, когда Вы звоните fuser на log.1 нет никакого процесса, который имеет активный дескриптор файла для этого файла.

Можно моделировать это путем выполнения while цикл внутри a list

(while true; do echo $(date); sleep 1; done) >> log

И оба logtest.sh и logtest.c завершится, неважно, который SIGNAL Вы отправляете, потому что Вы не обрабатываете сигнал. С bash это может быть, покончили trap '<COMMAND>' USR1 (смотрите на man bash-builtins). Но я понятия не имею, как это сделано в C (никогда lerned C).

1
ответ дан 27 May 2015 в 02:41

Другие вопросы по тегам:

Похожие вопросы: