Соответствует ли POSIX использование функции оболочки в конвейере?
Можно ли использовать функцию оболочки в конвейере?
Скажем, у меня была функция, которая действовала как grep
, называется mygrep
, Есть ли способ, используя только функции оболочки POSIX, чтобы иметь возможность вызыватьmygrep
как это:
if ps | mygrep foo ; then
echo "process foo is running"
fi
Или трубопровод ограничен только внешними командами?
2 ответа
Да. Смотрите этот документ .
В разделе "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
Вы должны использовать форму oneliner или упаковать выражение в ${}. В той форме, которую вы написали как bash-скрипт, это невозможно.