2016-11-15 2 views
4

Как закрыть программу, если поток потока простаивает в течение определенного периода времени?Bash: закрыть, если труба IO не используется

Скажем, например:

someprogram | closeidlepipe -t 500 | otherprogram

Есть ли какая-то программа closeidlepipe, которые могут закрыть, если простаивает в течение периода (-t 500)?

timeout может закрываться после определенного периода, но не с «незанятым» отличием.

ОБНОВЛЕНИЕ

Важно отметить, что someprogram выводит бесконечный поток двоичных данных. Данные могут содержать нулевой символ \0 и должны быть переданы по протоколу.

+0

мужчина 3 выбрать; должно быть кодирование в час. – Joshua

ответ

1

Вот общая форма сердца программы, которая делает это.

while(1) { 
    struct timeval tv; 
    tv.m_sec = 0; 
    tv.m_usec = 500000; 
    int marker = 1; 
    select(1, &marker, NULL, NULL, &tv); 
    if (marker == 0) exit(1); 
    char buf[8192]; 
    int n = read(0, buf, 8192); 
    if (n < 0) exit(2); 
    char *b = buf; 
    while (n) 
    { 
     int l = write(1, b, n); 
     if (l <= 0) exit(3); 
     b += l; 
     n -= l; 
    } 
} 
+0

Не будет ли этот блок для чтения, если доступно менее 8192 байт? – Climax

+1

Nope. read() возвращает только то, сколько читается в этом случае. – Joshua

+0

Только если дескриптор файла установлен в неблокирующий – Climax

1

В здании read есть опцион тайм-аут -t.

someprogram | 
    while :; do 
    IFS= read -d'' -r -t 500 line 
    res=$? 
    if [[ $res -eq 0 ||)); then 
     # Normal read up to delimiter 
     printf '%s\0' "$line" 
    else 
     # Either read timed out without reading another null 
     # byte, or there was some other failure meaning we 
     # should break. In neither case did we read a trailing null byte 
     # that read discarded. 
     [[ -n $line ]] && printf '%s' "$line" 
     break 
    fi 
    done | 
    otherprogram 

read Если время ожидания после 500 секунд, цикл while будет выходить и средняя часть трубопровода закрывается. someprogram получит сигнал SIGCHLD в следующий раз, когда попытается записать его конец этого канала, что позволит ему выйти.

+0

Если я не хотел читать строки за строкой, а скорее как можно больше? Должен ли я использовать '-n 4096' или что-то подобное? Предполагается, что это бесконечный поток для моего случая использования. – Climax

+0

Также будет корректно работать printf для двоичных данных, например, разрешить null (0x00) в строке без остановки? – Climax

+0

Это повышает точную точку, которая заключается в том, что 'read' собирается отбросить любой разделитель, используемый для определения строки. Вам также придется написать разделитель, * если * 'read' на самом деле вышло из строя. Чем больше я думаю об этом, тем меньше я думаю, что это хорошая идея. – chepner