Процесс замещения сломан трубой - PullRequest
0 голосов
/ 14 февраля 2019

Я сегодня сделал глупость:

read x <( ps -fu $LOGNAME | grep ' /usr/bin/ps$' )

Она висела, никогда не возвращалась.Мне пришлось это сломать.

Некоторые из вас совершенно справедливо смеются надо мной прямо сейчас.:)

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

Ответы [ 2 ]

0 голосов
/ 14 февраля 2019

Если вы замените read x на cat, сколько времени потребуется для запуска?

Проблема в том, что вы выполнили команду типа:

read x /dev/fd/63

(когда выможно было увидеть, запустив echo read x <(…)), и read сидел там, ожидая, пока вы наберете что-то, чтобы оно вставило x.

$ read x <( ps -fu $LOGNAME | grep ' /usr/bin/ps$' )
asc def
-bash: read: `/dev/fd/63': not a valid identifier
$

Оболочка ждала, когда вы что-то напечатаете, вот и все.Вы нетерпеливы.

Если вы хотите перенаправить ввод в read, вам необходим отдельный < для этого (мне нужно было изменить регулярное выражение grep, чтобы получить какой-либо вывод):

$ read x < <( ps -fu $LOGNAME | grep ' /usr/bin/ps' )
$ echo $x
501 16166 16164 0 7:50AM ttys000 0:00.00 grep /usr/bin/ps
$

Обратите внимание, что при прямом перенаправлении, как показано в последней команде read, будет прочитана только первая строка ввода из подстановки процесса;остальное будет потеряно.Если вам нужно обработать несколько строк в цикле while, вам нужно перенаправить весь цикл:

while read x
do
    whatever -with "$x"
done < <(ps -fu $LOGNAME | grep ' /usr/bin/ps')

См. Также руководство Bash по Замена процесса , где говорится:

Подстановка процесса позволяет ссылаться на вход или выход процесса, используя имя файла.

Результатом является имя файла (по крайней мере на Mac это занимаетформу /dev/fd/xx для некоторого числового значения xx), которое можно использовать для ссылки на выходные данные команд в подстановке процесса.

0 голосов
/ 14 февраля 2019

Подстановка процесса перенаправляет стандартный вывод на чтение.Ничто не идет в трубу к grep.

Соответственно, grep терпеливо ждет и блокируется, а цепочка команд никогда не завершается.

Я сделал это так:

read x pid x <<< "$( ps -fu $LOGNAME | grep ' /usr/bin/ps$' )"

Это работаетхорошо.Весь этот процесс запускается, создается выходная строка, и , а затем результат передается read.

Должен обратить внимание на поток данных.:)

...