lines=$(grep '^[^:]\+::' /etc /shadow)
Run Code Online (Sandbox Code Playgroud)
这整个命令是什么意思?
什么'^[^:]\+::'意思?
如果我把这样的if else声明:
if [ "$lines" == "" ]; then
Run Code Online (Sandbox Code Playgroud)
它会显示(这是我想要的)密码为空的用户吗?
grep是g/<RE>/p在ed/ ex(因此得名)中实现命令的命令,也就是说,它会p打印与给定的regular xpression e(简称 regex 或 regexp)匹配的行。
这里'^[^:]\+::'是正则表达式(引用是为了 shell 不特别处理其中的一些字符)。更准确地说(因为有几种实现grep并且大多数可以处理正则表达式的几种变体),它是一个 GNU Basic 正则表达式。
正则表达式是用于匹配字符串的模式。grep将每一行的内容与该模式进行比较并打印那些匹配的内容。
^是在要匹配的字符串的开头匹配的基本正则表达式运算符。我们说它将搜索锚定在字符串的开头,否则搜索将在该行内的任何位置。
[^:] 匹配任何字符,但 :
\+是一个 GNU 特定的非标准正则表达式运算符(尽管现在我们发现其他实现支持它),它意味着一个或多个前面的原子。这是标准\{1,\}基本正则表达式运算符的简写。
: 并不特殊并且与自身匹配。
因此,这里的正则表达式匹配以一个或多个字符序列开头的行,而不是:后跟两个:字符。
在 的上下文中/etc/shadow,这意味着它匹配具有至少 3 个字段且用户名字段不为空但密码字段为空的条目(这通常意味着用户无需密码即可登录)。它将匹配上root::,x::whatever而不是对root:x:或::whatever或root:。
grep 还通过其退出状态报告它是否与任何行匹配:
shell 分配的退出状态是在命令替换中运行的最后一个命令的退出状态。
例如,退出状态
var=$(exit 2)$(exit 4)
Run Code Online (Sandbox Code Playgroud)
将是 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
Run Code Online (Sandbox Code Playgroud)