echo "$password" | grep -q [A-Z]
-q
这个命令的作用是什么?
答案1
-q
告诉grep
一旦找到与模式匹配的行就以成功退出状态退出,如果在任何输入中都没有找到匹配行则以失败状态退出,否则不在标准输出上打印任何内容。
它通常用于以下情况:
if grep -q foo file; then
echo file contains foo
fi
或者:
find . -type f -exec grep -q foo {} \; \
-exec printf '"%s" contains foo\n' {} \;
或者:
<"$file" grep -q -xFe "$expected_line" ||
die "Expected line not found in $file"
在这里,您的代码示例由于以下几个原因是错误的:
[A-Z]
也是一个 shell glob 运算符,因此应该加引号,以便将[A-Z]
参数按字面意思传递给grep
.例如,如果当前目录中有名为A
、Z
和的文件X
,shell 会将 扩展[A-Z]
到这些文件,因此您最终会运行在和文件中grep -q A X Z
查找的文件。A
X
Z
- 模式匹配的内容
[A-Z]
随区域设置的不同而变化,并且通常或多或少是随机的。要ABCDEFGHIJKLMNOPQRSTUVWXYZ
按照使用者通常的意图来匹配任一字母[A-Z]
,您需要[ABCDEFGHIJKLMNOPQRSTUVWXYZ]
. echo
不能用于输出任意数据,因为具体取决于实现,它会破坏包含反斜杠和/或以-
.- 另请注意,如果输入不是文本,则 的行为
grep
未指定,因此您可能需要首先检查 的内容$password
在用户区域设置中是否为有效文本。
所以在这里:
if
printf '%s\n' "$password" | grep -q '[ABCDEFGHIJKLMNOPQRSTUVWXYZ]'
then
echo the password contains at least one ASCII uppercase letter
fi
或者:
if
printf '%s\n' "$password" | grep -q '[[:upper:]]'
then
echo "the password contains at least one letter considered uppercase in the user's locale"
fi
会更正确。虽然在 POSIX shell 中,你不需要grep
,你可以这样做:
case $password in
(*[ABCDEFGHIJKLMNOPQRSTUVWXYZ]*) echo contains ASCII uppercase;;
(*[[:upper:]]*) echo no ASCII uppercase, but some other uppercase;;
(*) echo no uppercase;;
esac
答案2
-q,--安静,--沉默
抑制正常输出。即使出现错误,搜索也会在第一次命中后立即结束,并返回零状态。