lines=$(grep '^[^:]\+::' /etc /shadow)
整个命令是什么意思?
这是什么'^[^:]\+::'
意思?
如果我if else
这样声明:
if [ "$lines" == "" ]; then
它会显示(这就是我想要的)密码为空的用户吗?
答案1
grep
是实现/g/<RE>/p
中的命令(因此得名)的命令,也就是说,它会打印与给定的常规表达式(简称 regex 或 regexp)匹配的行。ed
ex
p
r
e
这里,'^[^:]\+::'
是正则表达式(带引号,这样 shell 就不会特殊对待其中一些字符)。更准确地说(因为正则表达式有多种实现,grep
并且大多数可以处理正则表达式的多种变体),它是一个 GNU Basic 正则表达式。
正则表达式是用于匹配字符串的模式。grep
将每一行的内容与该模式进行比较并打印匹配的内容。
^
是基本的正则表达式运算符,匹配要匹配的字符串的开头。我们说它将搜索锚定在字符串的开头,否则搜索将在该行内的任何位置。[^:]
匹配任何字符,但是:
\+
是一个 GNU 特定的非标准正则表达式运算符(尽管现在我们发现其他支持它的实现),这意味着一个或多个前面的原子。它是标准基本正则表达式运算符的简写\{1,\}
。:
并不特殊,而且很匹配。
所以这里的正则表达式匹配的行开始包含一个或多个字符的序列,后面:
跟两个:
字符除外。
在 的上下文中/etc/shadow
,这意味着它匹配至少具有 3 个字段的条目,并且用户名字段不为空但密码字段为空(这通常意味着用户无需密码即可登录)。它将在root::
,上匹配x::whatever
,但在root:x:
or 或::whatever
上不匹配root:
。
grep
还通过退出状态报告它是否匹配任何行:
- 如果至少有一场比赛,则成功
- 否则失败或发生错误。
shell 分配的退出状态是命令替换中运行的最后一个命令的退出状态。
例如,退出状态
var=$(exit 2)$(exit 4)
将是 4。
所以在这里,你可以这样做:
if lines=$(grep '^[^:]\+::' /etc/shadow); then
printf 'There are users with an empty password:\n%s\n' "$lines"
else
printf 'OK, no user with empty passwords'
fi
答案2
grep '^[^:]\+::' /etc/shadow
不会显示任何内容,因为正则表达式模式不正确。
我猜您会找到没有与系统帐户关联的密码的用户。在这种情况下,请执行以下操作:
grep '^[^:]\+:.:' /etc/shadow
让我们来分解一下:
^[^:]\+
将找到从行首到下一行的部分,:
即用户名用户名后面将跟随一个
:
、由正则表达式标记指示的任何单个字符.
(可能是!
或*
),然后是一个:
。