Read pipe timeout linux

Linux pipes tips & tricks

Pipe — что это?

Pipe (конвеер) – это однонаправленный канал межпроцессного взаимодействия. Термин был придуман Дугласом Макилроем для командной оболочки Unix и назван по аналогии с трубопроводом. Конвейеры чаще всего используются в shell-скриптах для связи нескольких команд путем перенаправления вывода одной команды (stdout) на вход (stdin) последующей, используя символ конвеера ‘|’:

grep выполняет регистронезависимый поиск строки “error” в файле log, но результат поиска не выводится на экран, а перенаправляется на вход (stdin) команды wc, которая в свою очередь выполняет подсчет количества строк.

Логика

Конвеер обеспечивает асинхронное выполнение команд с использованием буферизации ввода/вывода. Таким образом все команды в конвейере работают параллельно, каждая в своем процессе.

Размер буфера начиная с ядра версии 2.6.11 составляет 65536 байт (64Кб) и равен странице памяти в более старых ядрах. При попытке чтения из пустого буфера процесс чтения блокируется до появления данных. Аналогично при попытке записи в заполненный буфер процесс записи будет заблокирован до освобождения необходимого места.
Важно, что несмотря на то, что конвейер оперирует файловыми дескрипторами потоков ввода/вывода, все операции выполняются в памяти, без нагрузки на диск.
Вся информация, приведенная ниже, касается оболочки bash-4.2 и ядра 3.10.10.

Простой дебаг

Исходный код, уровень 1, shell

Т. к. лучшая документация — исходный код, обратимся к нему. Bash использует Yacc для парсинга входных команд и возвращает ‘command_connect()’, когда встречает символ ‘|’.
parse.y:
Также здесь мы видим обработку пары символов ‘|&’, что эквивалентно перенаправлению как stdout, так и stderr в конвеер. Далее обратимся к command_connect():make_cmd.c:
где connector это символ ‘|’ как int. При выполнении последовательности команд (связанных через ‘&’, ‘|’, ‘;’, и т. д.) вызывается execute_connection():execute_cmd.c:

PIPE_IN и PIPE_OUT — файловые дескрипторы, содержащие информацию о входном и выходном потоках. Они могут принимать значение NO_PIPE, которое означает, что I/O является stdin/stdout.
execute_pipeline() довольно объемная функция, имплементация которой содержится в execute_cmd.c. Мы рассмотрим наиболее интересные для нас части.
execute_cmd.c:
Таким образом, bash обрабатывает символ конвейера путем системного вызова pipe() для каждого встретившегося символа ‘|’ и выполняет каждую команду в отдельном процессе с использованием соответствующих файловых дескрипторов в качестве входного и выходного потоков.

Исходный код, уровень 2, ядро

Обратимся к коду ядра и посмотрим на имплементацию функции pipe(). В статье рассматривается ядро версии 3.10.10 stable.
fs/pipe.c (пропущены незначительные для данной статьи участки кода):
Если вы обратили внимание, в коде идет проверка на флаг O_NONBLOCK. Его можно выставить используя операцию F_SETFL в fcntl. Он отвечает за переход в режим без блокировки I/O потоков в конвеере. В этом режиме вместо блокировки процесс чтения/записи в поток будет завершаться с errno кодом EAGAIN.

Максимальный размер блока данных, который будет записан в конвейер, равен одной странице памяти (4Кб) для архитектуры arm:
arch/arm/include/asm/limits.h:
Для ядер >= 2.6.35 можно изменить размер буфера конвейера:
Максимально допустимый размер буфера, как мы видели выше, указан в файле /proc/sys/fs/pipe-max-size.

Tips & trics

В примерах ниже будем выполнять ls на существующую директорию Documents и два несуществующих файла: ./non-existent_file и. /other_non-existent_file.

Перенаправление и stdout, и stderr в pipe

или же можно использовать комбинацию символов ‘|&’ (о ней можно узнать как из документации к оболочке (man bash), так и из исходников выше, где мы разбирали Yacc парсер bash):

Перенаправление _только_ stderr в pipe

Shoot yourself in the foot
Важно соблюдать порядок перенаправления stdout и stderr. Например, комбинация ‘>/dev/null 2>&1′ перенаправит и stdout, и stderr в /dev/null.

Читайте также:  Dns spoofing with kali linux
Получение корректного кода завершения конвейра

По умолчанию, код завершения конвейера — код завершения последней команды в конвеере. Например, возьмем исходную команду, которая завершается с ненулевым кодом:
И поместим ее в pipe:
Теперь код завершения конвейера — это код завершения команды wc, т.е. 0.

Обычно же нам нужно знать, если в процессе выполнения конвейера произошла ошибка. Для этого следует выставить опцию pipefail, которая указывает оболочке, что код завершения конвейера будет совпадать с первым ненулевым кодом завершения одной из команд конвейера или же нулю в случае, если все команды завершились корректно:
Shoot yourself in the foot
Следует иметь в виду “безобидные” команды, которые могут вернуть не ноль. Это касается не только работы с конвейерами. Например, рассмотрим пример с grep:
Здесь мы печатаем все найденные строки, приписав ‘new_’ в начале каждой строки, либо не печатаем ничего, если ни одной строки нужного формата не нашлось. Проблема в том, что grep завершается с кодом 1, если не было найдено ни одного совпадения, поэтому если в нашем скрипте выставлена опция pipefail, этот пример завершится с кодом 1:
В больших скриптах со сложными конструкциями и длинными конвеерами можно упустить этот момент из виду, что может привести к некорректным результатам.

Источник

lnguin

/* This example program demonstrates how to read and write a raw data in a serial port.
Reading the serial port is handled with timeout. */

#include // standard input / output functions
#include // string function definitions
#include // UNIX standard function definitions
#include // File control definitions
#include // Error number definitions
#include // POSIX terminal control definitionss
#include // time calls

int fd;
int read_port_flag = 0;
struct serial_data
<
unsigned char len; /* data length */
char data[32] __attribute__((aligned(32)));
>;

int openPort(const char* port)
<
fd = open(port, O_RDWR | O_NOCTTY);
if(fd == -1)
<
return (-1);
>
else
<
struct termios port_settings;
bzero(&port_settings, sizeof(port_settings));

/* enable the receiver and set local mode */
port_settings.c_cflag |= (CLOCAL | CREAD);

/* set no parity, stop bits, data bits */
port_settings.c_cflag &=

CSTOPB;
/* set character size as 8 bits */
port_settings.c_cflag &=

CSIZE;
port_settings.c_cflag |= CS8;
/* Raw input mode, sends the raw and unprocessed data ( send as it is) */
port_settings.c_lflag &=

(ICANON | ECHO | ISIG);
/* Raw output mode, sends the raw and unprocessed data ( send as it is).
* If it is in canonical mode and sending new line char then CR
* will be added as prefix and send as CR LF
*/
port_settings.c_oflag =

int send_port(struct serial_data *send_data)
<
if ((write(fd, send_data->data, send_data->len)) != send_data->len)
<
return (-1);
>

void set_port_read_min_size(int min_size)
<
struct termios settings;

/* set the minimimum no. of chracters to read in each
* read call.
*/
settings.c_cc[VMIN] = min_size;
/* set “read timeout between characters” as 100 ms.
* read returns either when the specified number of chars
* are received or the timout occurs */
settings.c_cc[VTIME] = 1; /* 1 * .1s */

if (tcsetattr (fd, TCSANOW, &settings))
<
/* handle error */
>
>

void read_port()
<
struct serial_data recv_data;
int recvbytes = 0;
int maxfd = fd + 1;
int index = 0;
/* set the timeout as 1 sec for each read */
struct timeval timeout = <1, 0>;
fd_set readSet;

/* set the “mininum characters to read” */
set_port_read_min_size(16);
read_port_flag = 1;

/* select() – returns 0 on timeout and -1 on error condtion */
if (!read_port_flag)
<
return;
>
>

Источник

Timeouts

Being KrakenD an API Gateway that talks to other services, being able to control the waiting times for different aspects is crucial. KrakenD will allow you to fine-tune these settings.

The timeouts can apply to:

  • The duration of the whole pipe (from user request to user response)
  • The HTTP request related timeouts

Additionally, you can control the number of maximum IDLE connections.

Pipe timeouts

Global timeout

The timeout key in the krakend.json at the root level is used in the first place to apply a default timeout for the whole duration of the pipe (and not only the connection to the backends). The timeout takes into account all the time involved between the request, the fetching of the data, manipulation and any other middleware. You can see it is an end-user timeout.

Читайте также:  Radeon hd 7560d linux

Endpoint-specific timeout

Even the timeout value in the root level sets a default timeout for all the endpoints, you can override it later on any specific endpoints.

To do so, just place it inside the desired endpoint:

The example above will use 1 second timeout for the /splash endpoint and 2000 milliseconds for all the other endpoints.

What happens when the timeout is reached?

When the timeout for a pipe is reached, the request is canceled and the user receives an HTTP status code 500 Internal Server Error

HTTP Request timeouts

In addition to the timeouts for the whole pipe, you can configure the specific HTTP layer timeouts. All the settings below work just like the pipeline timeouts. If you place this values in an endpoint, they will override the global setting.

HTTP Read Timeout

Maximum duration for reading the entire HTTP request, including the body.

This timeout does not let Handlers make per-request decisions on each request body’s acceptable deadline.

HTTP Write Timeout

Maximum duration before timing out writes of the response.

It is reset whenever a new request header is read. Like HTTP Read Timeout, it does not let Handlers make decisions on a per-request basis.

HTTP Idle Timeout

Maximum amount of time to wait for the next request when keep-alives are enabled.

If IdleTimeout is zero, the value of ReadTimeout is used. If both are zero, ReadHeaderTimeout is used.

HTTP Read Header Timeout

Amount of time allowed to read request headers.

The connection’s read deadline is reset after reading the headers and the Handler can decide what is considered too slow for the body.

Time units

The time units you can use to specify timeouts are integers (not floats) using any of these units:

  • Nanoseconds: ns
  • Microseconds: us , or µs
  • Milliseconds: ms
  • Seconds: s

It is also available although you should never use them:

Examples of equivalent timeouts in different units are:

Unresolved issues?

The documentation is only a piece of the help you can get! Whether you are looking for Open Source or Enterprise support, see more support channels that can help you.

The Ultra-High performance Open Source API Gateway with middlewares

KrakenD helps application developers release features quickly by eliminating all the complexities of SOA architectures while offering a unique performance.

Источник

memset’s blog

Timeout on Named Pipes

Hi. In this post, I will show you how make a timeouted namedpipe with the WIN32 API: the msdn’s manual doesn’t explain how to do it.
The named pipes are an IPC’s method by which we can send data to an other process (like a son process).

This solution is useful when for example we have a parent process A that create a son process B. We want send data from A to B through the namedpipe. A has to create the namedpipe and connect to it. When A connects to the pipe, it waits until B opens the pipe allowing data transfer.
But, if B die before opening the pipe, then A will wait indefinitely.
To resolve this problem, we need to set a maximum timeout to wait at the end of which we are sure that there was some problem.

So, you have to create your namedpipe (msdn man) that you need:

In this example, I have created a namedpipe named PIPE_NAME, duplex, byte oriented, overlapped, etc..
Now we want to connect us to the namedpipe so we can send our data:

So, what have we done?
In the line 8, we create a dummy event on which we will wait. In the line 10 we try to connect to the namedpipe “hpipe” using the ConnectNamedPipe() function (msdn man) . This function will return an error because we are using it in overlapped mode: so we have to check the type of error (line 14):

Читайте также:  Где хранятся резервные копии itunes mac os

1 – ERROR_PIPE_CONNECTED: the client is connected;
2 – ERROR_IO_PENDING: we are waiting the client’s connection: we can wait PIPE_TIMEOUT_CONNECT ms (10 seconds) using the WaitForSingleObject() (msdn man) on the ol.hEvent. If the function succeed, we must just have to check the result of the GetOverlappedResult() (msdn man). Otherwise we delete all the I/O pending operations (msdn man).

At the end (line 45), if ret != 0, we can send our data through the WriteFile() function (line 45) (msdn man).
For any question, you can use comments. 🙂
Bye.

Источник

ИТ База знаний

Курс по Asterisk

Полезно

— Узнать IP — адрес компьютера в интернете

— Онлайн генератор устойчивых паролей

— Онлайн калькулятор подсетей

— Калькулятор инсталляции IP — АТС Asterisk

— Руководство администратора FreePBX на русском языке

— Руководство администратора Cisco UCM/CME на русском языке

— Руководство администратора по Linux/Unix

Серверные решения

Телефония

FreePBX и Asterisk

Настройка программных телефонов

Корпоративные сети

Протоколы и стандарты

Использование timeout в Linux с примерами

Все имеет начало и конец

3 минуты чтения

Вот вы пользователь Linux машины. И вот вам захотелось запустить какую-нибудь команду только на определенное время, и вы задаете вопрос — как это сделать? А вот как — использовать команду timeout .

Мини — курс по виртуализации

Знакомство с VMware vSphere 7 и технологией виртуализации в авторском мини — курсе от Михаила Якобсена

Как взять timeout — об использовании команды

Базовый синтаксис

Как и следовало ожидать, синтакс у команды экстремально прост: сама команда timeoutопциидлительность выполнения (можно даже с единицами измерения) — целевая команда

Единицы измерения для указания длительности:

  • s — секунды (­стоит по умолчанию)
  • m — минуты
  • h — часы
  • d — дни

Если вы не укажете никакого параметра по длительности, команда не будет активирована.

  • timeout 5 ping 1.1.1.1 — пингуем 1.1.1.1 5 секунд
  • timeout 5m ping 1.1.1.1 — пингуем 1.1.1 5 минут
  • timeout 5.5h ping 1.1.1.1 — 5,5 часов пингуем 1.1.1

Если у вас есть необходимость, можно запустить команду с добавкой sudo (если для целевой команды требуются права суперпользователя):

sudo timeout 100 tcpdump -n -w dump.pcap

Сообщение с космосом или отправка определенного сигнала исполняемому процессу

Если вы не указали какой-то особый сигнал, по умолчанию передается SIGTERM (сигнал о том, что надо бы мягко терминировать процесс). Однако, если вы укажете ключ -s после команды timeout, вы можете указать любой другой допустимый сигнал. К примеру: sudo timeout -s SIGKILL ping 1.1.1.1 или sudo timeout -s 9 ping 1.1.1.1

Обе команды выше идентичны, и если вы хотите увидеть весь список сигналов, просто введите kill -l

Как убить процесс, если он завис

Как вы уже поняли, SIGTERM — это сигнал, который отправляется после истечения таймаута, но он легко может быть проигнорирован процессом, и тогда процесс не остановится. Для уверенности в смерти процесса, нужно использовать ключ -k и некое временное значение. Тогда после окончания таймаута будет отправляться сигнал SIGKILL, который процесс не сможет проигнорировать при всем желании. В примере ниже команда выполняется одну минуту, и, если в течение 10 секунд после окончания таймаута она не «умирает», отправляется сигнал SIGKILL и «добивает» процесс:

sudo timeout -k 10 1m ping 1.1.1.1

Сохраняем статус

Команда timeout всегда возвращает значение 124 после истечения указанного времени или возвращает статус «exit» управляемой команды (той, что вы вводите после команды timeout). Таким образом, вы можете использовать ключ — -preserve-status :

timeout —preserve-status 10 ping 1.1.1.1

Запуск команды явно, а не за кулисами

По умолчанию, timout работает в бэкграунде, и если вы хотите обратного (вдруг после запуска управляемой команды потребуется какой-нибудь пользовательский ввод), нужно использовать ключ -foreground:

timeout —foreground 10m ./bestscripteva.sh

Заключение

В 99% процентов случаев команда timeout требует всего двух аргументов и ни одного факта: времени исполнения и самой исполняемой команды. Однако, вы теперь знаете и другие фишки использования этой замечательной команды.

Мини — курс по виртуализации

Знакомство с VMware vSphere 7 и технологией виртуализации в авторском мини — курсе от Михаила Якобсена

Источник

Оцените статью