我正在编写一个 bash 脚本,其中我想检查传递给它的参数之一是否是有效的组。
我有线
if [ `grep -c -e '\b$2\b' /etc/group` -eq 0 ]; then
echo "Error: $2 is not a valid group."
else
这总是告诉我有效的组无效。
我认为这是一个逃避问题;我认为这是在寻找一个名为 的团体$2
。错误消息正确显示了传递的参数。但是我不确定我是否$2
正确地在反引号内转义。
我如何让这条线工作?
答案1
使用grep
's-q
选项比命令替换更有效。
if ! grep -q -e "^$2:" /etc/group; then
echo "Error: $2 not a valid group" >&2
fi
问题是单引号 ( '
) 会阻止 shell 变量扩展 ( $
)。您需要使用双引号 ( "
)。
答案2
grep -q -e "^$2:" /etc/group
应该管用。
(单引号防止插值)
答案3
由于单引号,您正在按字面意思传递\b$2\b
。grep
要允许$2
扩展到参数的值,请使用"$2"
。此外,反引号之间的引用可能会变得很棘手; use $(…)
,其含义与`…`
(命令替换)相同,但在引用方面表现良好。
if [ $(grep -c -e "\b$2\b" /etc/group) -eq 0 ]; then …
接下来,计算匹配项过于复杂:您可以使用grep
的返回状态来了解是否存在匹配项。传递-q
选项表明grep
您对任何输出都不感兴趣,只对返回状态感兴趣。
if ! grep -q -e "\b$2\b" /etc/group; then …
接下来,你的搜索是错误的。您正在查找单词$2
,但它可能与用户名、组名中包含标点符号的部分或一些更奇特的不匹配项匹配。组名称是第一个以冒号分隔的字段,因此请搜索该字段。
if ! grep -q -e "^$2:" /etc/group; then …
请注意,您可能需要清理输入:$2
不得包含任何特殊字符grep
或组分隔符。
case $2 in
*[][\.*^$]*) echo "Unsupported character in the group name";;
esac
if ! grep -q -e "^$2:" /etc/group; then …
最后,grep /etc/group
如果您可以避免的话,这不是正确的工具。您只能通过这种方式找到本地组名称,而不能找到来自 NIS 或 LDAP 或异常设置的组。大多数现代 unice(至少 Solaris、Linux 和 *BSD)都有getent
命令从系统数据库(包括组数据库)检索条目。
if ! getent group "$2" >/dev/null; then …
(对于用户来说,不要查看/etc/passwd
,而是使用getent passwd
,或者更方便地调用id
.)