我有几个命令可以直接在命令行上运行,不会出现任何问题,当我运行它们并替换$1
为我想要在 LDAP 中签入的实际组名称时。现在我想把它变成一个参数化函数,但我无法得到错误消息或回显来打印任何内容。
如何将下面的代码添加到命令行上的 .zshrc 中,将其转换为可以在 zsh 中调用的函数? (针对公开发布略有调整)
alias ldapuserlookup=" /usr/bin/ldapsearch -LLL -x -h ldap.com -s sub -b 'ou=Groups,o=.com' '(cn=$1)' memberuid | sed 's/memberuid: //g')"
预期输出:
username1
username2
username3
这个问题肯定已经被问过一百万次了,但我只是不知道在搜索中输入哪些关键字才能给我一个有用的例子。很多都是为了 bash,或者不适合我正在做的事情。
答案1
您可以向下滚动到解决方案的末尾,但由于了解实际发生的情况很重要,因此这里是完整的细分。
答案有三层:
1. 您提供的命令包含错误:)
参数末尾有一个额外的内容sed
,导致以下错误输出:
zsh: parse error near `)'
$(...)
(我猜这可能是尝试使用语法留下的)
2. 您正在使用别名来执行预期对用户提供的参数进行操作的命令。在这种情况下,您希望改用函数。
别名本质上只是 shell 助手,它们的预期目的是命令名称的字符串替换,通常带有附加选项标志,例如:alias ll='ls -al'
等alias grep='grep --color=auto'
。”此外,别名有多个警告,可以轻松破坏命令行为,但这些超出了特定范围回答这个问题。
在您的特定情况下,您想使用功能相反,因为它们旨在接受命令参数并根据需要解析它们。它们是两全其美的,因为它们的操作方式与别名类似 - 它们可以在全局以及在一个特定终端内动态初始化 - 而且还具有真实脚本的多功能性,但不需要创建脚本文件的额外麻烦。
为了将别名重新格式化为函数,您可以像这样声明它(注意:这还不是完整的解决方案):
ldap_userlookup(){
# It is standard practice to use '_' as separator function names
/usr/bin/ldapsearch -LLL -x -h ldap.com -s sub -b 'ou=Groups,o=.com' '(cn=$1)' memberuid | sed 's/memberuid: //g'
}
笔记:在命令前面添加
echo
是检查 shell 如何解析该特定命令的好方法。还可以set -x
用于完整的调试输出,但这可能非常冗长。
使用以下两个带前缀的声明echo
将说明解析所提供参数的差异:
alias testalias='echo "/usr/bin/ldapsearch -LLL -x -h ldap.com -s sub -b ou=Groups,o=.com (cn=$1) memberuid " '
test_func(){
echo "/usr/bin/ldapsearch -LLL -x -h ldap.com -s sub -b ou=Groups,o=.com (cn=$1) memberuid " }
- 坏的:使用声明的别名并运行
testalias argtest
我们获得:
/usr/bin/ldapsearch -LLL -x -h ldap.com -s sub -b ou=Groups,o=.com (cn=) memberuid testarg
这显然不是期望的行为,因为提供的参数被附加在命令的末尾,而不是我们的命令被告知期望 it ( cn=$1
)
- 好的:使用该函数
test_func argtest
我们得到:
/usr/bin/ldapsearch -LLL -x -h ldap.com -s sub -b ou=Groups,o=.com (cn=testarg) memberuid
**如您所见,我们声明的函数能够解析我们的命令行参数argtest
,然后放置在命令内正确的所需位置,即作为cn=
** 的参数
3.您正在使用'
变量参数,并且bash
和 都zsh
遵循以下规则:其中包含的变量'
不会扩展,但包含在内部的变量会"
扩展。
以下是您的命令(为了清楚起见再次删除管道) - 即使放置在函数内部 - 将如何根据使用的变量封装进行解析:
'
在函数内使用单引号引起来的变量
test_func(){
echo "/usr/bin/ldapsearch -LLL -x -h ldap.com -s su -b 'ou=Groups,o=.com'" '(cn=$1)' memberuid
}
执行中test_func argtest
输出不良:
/usr/bin/ldapsearch -LLL -x -h ldap.com -s su -b 'ou=Groups,o=.com' (cn=$1) memberuid
- 用双引号重新格式化函数
"
(保留旧的不需要的'
引号,以表明它将"
覆盖它们)
test_func(){
echo "/usr/bin/ldapsearch -LLL -x -h ldap.com -s su -b 'ou=Groups,o=.com'" "'(cn=$1)'" memberuid
}
执行中test_func argtest
良好的输出:
/usr/bin/ldapsearch -LLL -x -h ldap.com -s su -b 'ou=Groups,o=.com' '(cn=argtest)' memberuid
完整解决方案:
完整的函数声明(echo
删除、sed
附加管道、使用双引号)应该为您提供所需的行为:
ldap_userlookup () {
/usr/bin/ldapsearch -LLL -x -h "ldap.com" -s "sub" -b "ou=Groups,o=.com" "(cn=$1)" memberuid | sed 's/memberuid://g'
}
一旦你测试它并且它起作用了,你可以将它附加到你的 main 中~/.zshrc
,它将被加载到每个zsh
终端窗口中,或者你可以创建一个单独的~/.zsh_functions
文件,将此函数和其他自定义函数定义放入其中,然后用于source ~/.zsh_functions
加载它们根据需要进入您的 shell。