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
打印与给定的r
egular 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)