我正在尝试为 LDAP 条目编写一个漂亮的打印机,它只获取一次根 LDAP 记录,然后将输出通过管道传输到tee
每个部分调用漂亮的打印机。
为了便于说明,假设我的group_entry
函数返回特定 LDAP DN 的 LDIF。其中的细节并不重要,所以假设它总是返回:
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
我可以通过一些'ing 和'ing轻松地分别提取所有者和成员cut
。然后,我可以将这些辅助 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