У меня есть несколько функций, определенных таким образом:
function f {
read and process $1
...
echo $result
}
Я хочу собрать их вместе, чтобы вызов выглядел так f | g | h
.
Какую идиому я должен использовать для преобразования функции, работающей с аргументами, в чтение аргументов из стандартного ввода? Можно ли читать пары, кортежи аргументов из потока без необходимости экранировать их (например, завершать нулем)?
bash
shell-script
pipe
Rumca
источник
источник
h(g(f(...)))
либо каждая из функций читает из стандартного input (read x; ...
) и записывает в стандартный output (echo ...
).Ответы:
Один из возможных подходов - поместить
while...read
внутри ваших функций конструкцию, которая будет обрабатывать любые данные, поступившие в функцию через STDIN, работать с ней, а затем отправлять полученные данные обратно через STDOUT.Необходимо уделить внимание настройке
while ..read..
компонентов, поскольку они будут сильно зависеть от типов данных, которые они смогут надежно использовать. Там может быть оптимальная конфигурация, которую вы можете придумать.пример
Вот каждая функция сама по себе.
Вот они, когда мы используем их вместе.
Они могут принимать различные стили ввода.
источник
В качестве дополнения к ответу slm я провел некоторые эксперименты с кортежами, разделенными нулями, в качестве аргументов функции:
Примечания:
sayTuple
дважды читает запись с нулевым символом в конце,-d $'\0'
обрабатывая любое пространство, окружающее вводIFS=
.echo
назад записи в окружении-
Результат показывает, что он правильно обрабатывает ввод с нулем в конце, содержащий
\n
и\t
:Пожалуйста, добавьте предложения по улучшению в комментариях, это интересная тема.
источник
sayTuple() { arr=() ; while IFS= read -r -d $'\0' arg; do arr+="$arg"; done; echo "sayTuple: ${arr[@]}"; }
,IFS= read -r -d $'\0' -a arg
но я не мог заставить это работать. Это позволило бы удалитьwhile
, что кажется ненужным, но было единственным шаблоном, который я мог заставить работать.