存储命令的输出,同时还使用 if 语句的退出状态

Storing a command's output while also using exit status for an if statement

如何优化以下 Bash 代码?

if grep --quiet $pattern $fname; then
  echo "==> "$fname" <=="
  grep -n $pattern $fname
fi

首先它会扫描文件以查找 $pattern 的出现。如果找到任何结果,它会打印文件名,然后打印所有出现的结果。

你可以看到它做了两次相同的 grep。如果我可以存储第一次调用的结果然后再使用它们,那就完美了。

赋值不会更改 $? 的值,因此您可以在不修改逻辑的情况下添加一个:

if content=$(grep -n "$pattern" "$fname"); then
  echo "==> $fname <=="
  printf '%s\n' "$content"
fi

注意,这里所有的变量扩展都在双引号内。出于某种原因,您的原件明确地只在不加引号的情况下执行它们——这会导致字符串拆分和 glob 扩展发生;你几乎肯定不想要。


顺便说一句——您可以做一些事情,在生成其值的子 shell 中进行赋值修改命令 运行 的退出状态!使用 declareexportlocal 等执行赋值将导致该命令自己的退出状态替换被赋值的子 shell 的退出状态。

# here, the "local" will replace $? with 0
$ f() {
>   local foo=$(echo "bar"; exit 1)
>   echo "$?"
> }
$ f
0

...而...

# here, the "local" is separate, so the subshell's exit status survives
$ f() {
>   local foo
>   foo=$(echo "bar"; exit 1)
>   echo "$?"
> }
$ f
1