1

Можно ли использовать функцию оболочки в конвейере?

Скажем, у меня была функция, которая действовала как grep , называемая mygrep . Есть ли способ, используя только функции оболочки POSIX, чтобы вызвать mygrep следующим образом:

if ps | mygrep foo ; then
   echo "process foo is running"
fi

Или трубопровод ограничен только внешними командами?

2 ответа2

4

Да. Смотрите этот документ.

1. Вступление

В разделе «Shell and Utilities» в POSIX.1-2017 описываются команды и утилиты, предлагаемые прикладным программам в POSIX-совместимых системах.

От 2.9.2 Трубопроводы:

Конвейер представляет собой последовательность из одной или нескольких команд, разделенных оператором управления '|'.

С 2.9.5 Команда определения функции:

Функция - это пользовательское имя, которое используется как простая команда [...]

Формат команды определения функции следующий:

fname ( ) compound-command [io-redirect ...]

Из 2.9 Команды оболочки:

Команда является одной из следующих:

  • Простая команда [...]
  • [...]

Так | разделяет команды; команда может быть простой командой; Имя функции используется как простая команда. Ответ на ваш вопрос: да, этот синтаксис

some_command | some_function

определяется POSIX.


Это довольно просто попробовать (протестировано с помощью sh предоставленного dash в Debian 9):

mygrep() { grep "$@"; }

if ps | mygrep foo ; then
   echo "process foo is running"
fi

if ps | mygrep ps ; then
   echo "process ps is running"
fi

(ps | mygrep foo также обнаружит процесс foobar , если таковой имеется). Я понимаю, что этот вопрос выходит за рамки вашего вопроса, и мы можем его игнорировать).

В этом примере mygrep тривиален. Возвращает статус выхода своей последней (и единственной) команды. При построении функций с более сложной логикой вам может понадобиться специальный встроенный return для возврата желаемого состояния выхода.

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

if ps | mygrep ps >/dev/null ; then
   echo "process ps is running"
fi
-2

Вы должны использовать форму oneliner или упаковать выражение в $ {}. В той форме, которую вы написали как bash-скрипт, это невозможно.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .