2017-02-06 18 views
6

Я создал именованный канал для другого процесса для записи и хочу проверить, что другой процесс запущен правильно, но не знает его PID. Контекст running a command in screen, убедившись, что команда запущена правильно. Я надеялся, что это может работать:Проверьте, открыт ли именованный канал/FIFO для ввода

mkfifo /tmp/foo 
echo hello > /tmp/foo & 
lsof /tmp/foo 

К сожалению, lsof не сообщает echo. inotifywait может быть другим вариантом, но не всегда установлен, и я действительно хочу опросить только один раз, а не блокировать до некоторого события.

Есть ли способ проверить, открыт ли именованный канал для записи? Даже открытый вообще?


UPDATE:

После того, как оба конца соединены lsof, кажется, работает. Это фактически решает мою проблему, но, ради вопроса, мне было бы интересно узнать, можно ли обнаружить первоначальное перенаправление на именованный канал без чтения.

> mkfifo /tmp/foo 
> yes > /tmp/foo & 
> lsof /tmp/foo 
> cat /tmp/foo > /dev/null & 
> lsof /tmp/foo 
COMMAND PID  USER FD TYPE DEVICE SIZE/OFF  NODE  NAME 
yes  16915  user 1w FIFO 8,18  0t0 16660270 /tmp/foo 
cat  16950  user 3r FIFO 8,18  0t0 16660270 /tmp/foo 
+0

Когда вы говорите «открытое письмо», вы имеете в виду, что есть данные, доступные для чтения? Что, для вас, является FIFO, который не открыт для написания? – Fred

+1

Не тот ответ, который вы ищете, но вы можете написать файл .pid – teppic

+0

@Fred Может быть, «открыть для записи» - это неправильный термин, если вы считаете, что вопрос не имеет смысла. В идеале я хотел бы перечислить процессы, перенаправленные на этот именованный канал. То есть после 'mkfifo' и ничего больше, список должен быть пустым. Затем, после 'yes>/tmp/foo', я должен увидеть PID« yes »в списке. – jozxyqk

ответ

2

Update 2: После игры с Inotify-инструментов, не кажется, что должен быть способ, чтобы получить уведомление о том, что именованный канал был открыт для записи и блокировки. Вероятно, поэтому lsof не показывает трубку, пока у нее нет считывателя и писателя.

Обновление: После изучения именованных труб я не считаю, что существует какой-либо метод, который будет работать с именованными трубами самостоятельно. Рассуждения:

  • нет никакого способа, чтобы ограничить число писателей именованного канал (не прибегая к фиксации)
  • всех авторов блокируют, если нет читателя
  • не писатели не блокируют, если есть читатель (предположительно, пока буфера ядра не полные)

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

Примечание: Как указано в комментариях, если читатель существует и, по-видимому, достаточно быстр, наша тестовая запись не будет блокироваться, и тест по существу не удастся. Прокомментируйте приведенную ниже строку cat, чтобы проверить это.

#!/bin/bash 

is_named_pipe_already_opened_for_writing() { 
    local named_pipe="$1" 
    # Make sure it's a named pipe 
    if ! [ -p "$named_pipe" ]; then 
     return 1 
    fi 
    # Try to write zero bytes in the background 
    echo -n > "$named_pipe" & 
    pid=$! 
    # Wait a short amount of time 
    sleep 0.1 
    # Kill the background process. If kill succeeds, then 
    # the write was blocked indicating that someone 
    # else is already writing to the named pipe. 
    kill $pid 2>/dev/null 
} 

PIPE=/tmp/foo 

# Ignore any bash messages from killing below 
trap : TERM 

mkfifo $PIPE 
# a writer 
yes > $PIPE & 
# a reader 
cat $PIPE >/dev/null & 

if is_named_pipe_already_opened_for_writing "$PIPE"; then 
    echo "$PIPE is already being written to by another process" 
else 
    echo "$PIPE is NOT being written to by another process" 
fi 

jobs -pr | kill 2>/dev/null 
rm -f $PIPE 
+0

Да, это работает, если ничего не видно из трубы. – jozxyqk

+0

Я не тестировал это. Ну, это нехорошо. – Harvey

+0

Полагая определенную продолжительность сна (которая, если я правильно понимаю, должна дать достаточно времени для завершения тестового фонового процесса записи), кажется немного хрупкой. Не будет ли риск непредвиденных результатов в условиях сертификации (например, высокая загрузка процессора или ввода-вывода)? – Fred