无法理解如何检查命令的结果(在循环内部)

时间:2013-01-22 16:16:21

标签: bash

我正在做一个bash脚本,应该搜索用户是否曾登录过计算机,我来到下面这部分并且不知道该怎么做。

我创建了一个循环,它读取wtmp-files(已经复制和解压缩),并显示所有带有用户的行(这部分有效)。但是,当找不到用户时,脚本应该通知它,但我不知道该怎么做。

ls -1t $folder/wtmp* 2> /dev/null| while read filename ;
do
    last -f "${filename}" 2>/dev/null | grep $user | cut -c 1-7,40-63
done

我会感谢一个好的建议,人们: - )

2 个答案:

答案 0 :(得分:0)

在使用pipefail循环之前确定。 Pipefail是一个bash选项,它将在命令管道中返回最右边的非零错误状态。

例如,您的问题如下

last -f file | grep user | cut -c 1-7

 succeeds        fails      succeeds

但是默认情况下bash只会使用cut命令的退出代码作为管道的退出代码($?)

如果你

set -o pipefail

首先使用grep的退出状态

所以:

set -o pipefail
ls -1t $folder/wtmp* 2> /dev/null| while read filename ;
do
    last -f "${filename}" 2>/dev/null | grep $user | cut -c 1-7,40-63
    [[ $? -gt 0 ]] && echo "user not found in $filename"
done
set +o pipefail

答案 1 :(得分:0)

如果找不到请求的正则表达式,

grep将以非零退出状态退出,所以你 只需一次调用cut,然后通过一次调用grep,即可输出匹配行,或找不到任何调用,只需将所有调用的输出通过管道输送到最后 要执行的列表的另一部分。

for filename in "$folder"/wtmp*; do
  last -f "${filename}"     
done 2> /dev/null | cut -c 1-9,40-63 | grep $user || echo "$user not found"

此外,不需要调用ls,因为用作ls参数的glob可以被for循环直接用于迭代目录中的文件。

(我调整了字符范围,以便您获得完整的8个字符的用户名以及用于将用户名与时间戳分开的空格。)

相关问题