bash 理解 grep 命令的脚本

bash script with grep command understanding

我之前发布过类似的内容。我正在尝试使用打印出 mburkhar is logged on 的命令 $ ./user mburkhar 检查用户是否在线。我的程序运行正常,但如果我只键入 $ ./user mb,也会显示 mb is logged on。我拥有的很好,但是有没有办法完全匹配用户输入的内容,而不是稍微匹配前 2 个字符..?

这是我的程序,所以你可以看到我做了什么:

# Check if a user is logged on

if [ -z  ] ; then
    read user
else
    user=
fi

if [ `who | cut -d" " -f1 | grep ` ] ; then
    echo " is logged on"
else
    echo " is either not valid or logged on"
fi

您可以使用 grep 的 -w (--word-regexp) 选项来只匹配整个单词。在脚本中将 grep 替换为 grep -w 应该可以解决问题。

像这样指定字符串锚点的开始和结束:

if [ -z  ] ; then
    read user
else
    user="^$"
fi

if [ $(who | cut -d" " -f1 | grep $user | uniq ) ] ; then
    echo " is logged on"
else
    echo " is either not valid or logged on"
fi

我还添加了 uniq 以删除重复的匹配项,以防用户获得多个 tty,否则 [ 将退出:[: too many arguments

补充

-w 运行良好并得到广泛支持(GNU Grep、BSD Grep),但 it is not POSIX-compliant.

在你的情况下,假设你的输出行包含 just 一个用户名,没有别的,使用 -x - 匹配 entire 行 - 也有意义(它 POSIX 兼容的)。
此外,由于您正在搜索 文字 用户名,因此最好使用 grep-F 选项来指明这一点。

使用[ $(...) ](或[ `...` ])来测试命令的非空输出有点脆弱且效率低下;更好更简单的是:

  • 直接使用命令
  • 根据退出代码
  • 进行测试
  • 并在需要时抑制标准输出

    • grep-q 选项不仅抑制标准输出,而且通过在 first 找到匹配项(退出代码 0 表示成功):

      if who | cut -d' ' -f1 | grep -Fxq ""; then # ...
      

同样,[ -z ] 是脆弱的,因为如果传递带有嵌入空格的参数,它会中断 - 在 这种 情况下不太可能,但它是 (或者,如果您必须保持 POSIX 合规,[ -z "" ])。
[[ ... ]] 之外,习惯性地用双引号引用变量是有意义的,例如 grep 命令中的 </code>。</p> <p>如果我们把它们放在一起:</p> <pre><code># Check if a user is logged on if [[ -z ]]; then read user else user= fi if who | cut -d' ' -f1 | grep -Fxq ""; then echo " is logged on" else echo " is either not valid or logged on" fi