这个命令是什么意思?

1 command-line grep

lines=$(grep '^[^:]\+::' /etc /shadow) 
Run Code Online (Sandbox Code Playgroud)

这整个命令是什么意思?

什么'^[^:]\+::'意思?

如果我把这样的if else声明:

if [ "$lines" == "" ]; then 
Run Code Online (Sandbox Code Playgroud)

它会显示(这是我想要的)密码为空的用户吗?

Sté*_*las 5

grepg/<RE>/ped/ ex(因此得名)中实现命令的命令,也就是说,它会p打印与给定的regular xpression e(简称 regex 或 regexp)匹配的行。

这里'^[^:]\+::'是正则表达式(引用是为了 shell 不特别处理其中的一些字符)。更准确地说(因为有几种实现grep并且大多数可以处理正则表达式的几种变体),它是一个 GNU Basic 正则表达式。

正则表达式是用于匹配字符串的模式。grep将每一行的内容与该模式进行比较并打印那些匹配的内容。

  • ^是在要匹配的字符串的开头匹配的基本正则表达式运算符。我们说它将搜索锚定在字符串的开头,否则搜索将在该行内的任何位置。

  • [^:] 匹配任何字符,但 :

  • \+是一个 GNU 特定的非标准正则表达式运算符(尽管现在我们发现其他实现支持它),它意味着一个或多个前面的原子。这是标准\{1,\}基本正则表达式运算符的简写。

  • : 并不特殊并且与自身匹配。

因此,这里的正则表达式匹配以一个或多个字符序列开头的行,而不是:后跟两个:字符。

在 的上下文中/etc/shadow,这意味着它匹配具有至少 3 个字段且用户名字段不为空但密码字段为空的条目(这通常意味着用户无需密码即可登录)。它将匹配上root::x::whatever而不是对root:x:::whateverroot:

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)