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

sti*_*til 2 bash optimization sh

如何优化以下Bash代码?

if grep --quiet $pattern $fname; then
  echo "==> "$fname" <=="
  grep -n $pattern $fname
fi
Run Code Online (Sandbox Code Playgroud)

首先它扫描文件是否出现$pattern.如果找到任何结果,则会打印文件名,然后显示所有出现的结果.

你可以看到它做了grep两次相同的事情.如果我可以存储第一次调用的结果然后重复使用它,那将是完美的.

Cha*_*ffy 6

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

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

注意,这里,所有变量扩展都在双引号内.出于某种原因,你的原文只是明确地执行它们而不引用 - 这会导致字符串分裂和glob扩展; 你几乎肯定也不想要.


顺便说一句-有一些事情你可以做的是进行分配修改命令运行的退出状态的子shell产生它的价值!使用declare,export,local,等来执行分配将导致命令自己的退出状态,以取代子shell被分配.

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

... ...而

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