Я пытаюсь написать красивый принтер для записей LDAP, который только один раз извлекает корневую запись LDAP, а затем направляет вывод в tee
, который вызывает красивый принтер для каждого раздела.
Для иллюстрации скажем, что моя функция group_entry
возвращает LDIF определенного DN LDAP. Детали которых не важны, поэтому допустим, что он всегда возвращается:
dn: cn=foo,dc=example,dc=com
cn: foo
owner: uid=foo,dc=example,dc=com
owner: uid=bar,dc=example,dc=com
member: uid=foo,dc=example,dc=com
member: uid=baz,dc=example,dc=com
member: uid=quux,dc=example,dc=com
custom: abc123
Я могу легко выделить владельцев и участников по отдельности с помощью grep
и cut
ing. Затем я могу передать эти вторичные DN в другой поисковый запрос LDAP, чтобы получить их настоящие имена. В качестве примера предположим, что у меня есть функция pretty_print
, которая параметризуется по имени атрибута LDAP, которая выполняет все, что я только что упомянул, а затем красиво форматирует все с помощью AWK:
$ group_entry | pretty_print owner
Owners:
foo Mr Foo
bar Dr Bar
$ group_entry | pretty_print member
Members:
foo Mr Foo
baz Bazzy McBazFace
quux The Artist Formerly Known as Quux
Они отлично работают по отдельности, но когда я пытаюсь tee
их вместе, ничего не происходит:
$ group_entry | tee >(pretty_print owner) | pretty_print member
Members:
[Sits there waiting for Ctrl+C]
Очевидно, я неправильно понимаю, как это должно работать, но это ускользает от меня. Что я делаю неправильно?
ИЗМЕНИТЬ. Вот мой полный сценарий:
#!/usr/bin/env bash
set -eu -o pipefail
LDAPSEARCH="ldapsearch -xLLL"
group_entry() {
local group="$1"
${LDAPSEARCH} "(&(objectClass=posixGroup)(cn=${group}))"
}
get_attribute() {
local attr="$1"
grep "${attr}:" | cut -d" " -f2
}
get_names() {
# We strip blank lines out of the LDIF entry, then we always have "dn"
# followed by "cn" records; we strip off the attribute name and
# concatenate those lines, then sort. So we get a sorted list of:
# {{distinguished_name}} {{real_name}}
xargs -n1 -J% ${LDAPSEARCH} -s base -b % cn \
| grep -v "^$" \
| cut -d" " -f2- \
| paste - - \
| sort
}
pretty_print() {
local attr="$1"
local -A pretty=([member]="Members" [owner]="Owners")
get_attribute "${attr}" \
| get_names \
| gawk -F'\t' -v title="${pretty[${attr}]}:" '
BEGIN { print title }
{ print "-", gensub(/^uid=([^,]+),.*$/, "\\1", "g", $1), "\t", $2 }
'
}
# FIXME I don't know why tee with process substitution doesn't work here
group_entry "$1" | pretty_print owner
group_entry "$1" | pretty_print member
pretty_print owner
наследует стандартный вывод из того же места, что иtee
, что означает, чтоpretty_print member
получит дополнительный неожиданный ввод. - person chepner   schedule 13.03.2017pretty_print
, выполняющимися асинхронно, поэтому их вывод, вероятно, будет чередоваться, если они записывают в один и тот же файл. - person chepner   schedule 13.03.2017