如何优化下面的Bash代码?存储命令的输出,同时使用if语句的退出状态
if grep --quiet $pattern $fname; then
echo "==> "$fname" <=="
grep -n $pattern $fname
fi
首先它扫描文件发现$pattern
。如果找到任何结果,则会打印文件名称,然后显示所有出现的结果。
你可以看到它做了两次相同的grep
。如果我可以存储来自第一个电话的结果,然后再使用它们,那将是完美的。
如何优化下面的Bash代码?存储命令的输出,同时使用if语句的退出状态
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
注意,在这里,所有的变量扩展是双引号。出于某种原因,你的原始文件只是明确地执行它们而不是引用 - 这会导致字符串分割和全局扩展发生;你几乎肯定不想要。
顺便说一句 - 有些事情你能做到这将进行分配修改命令运行的退出状态的子shell产生它的价值!使用declare
,export
,local
等来执行分配将导致该命令自己的退出状态替换被分配的子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
这是一个+2的答案! –
考虑运行通过http://shellcheck.net/你的代码,顺便说一句 - 它会找到引用错误我在这里指出。 'echo“==>”$ fname“<==”'只是特别愚蠢 - 它来得非常近*,然后在'$ fname'扩展之前结束引号!见http://mywiki.wooledge.org/BashPitfalls –
中的项目#14谢谢!我在脚本的其余部分遇到了很多这些问题。我从http://www.grymoire.com/Unix/Sh.html学习shell脚本,它有许多怪癖。 – stil
布鲁斯的网页上有很多好东西。也就是说,如果你正在寻找超越POSIX sh的shell的资源,我倾向于建议http://mywiki.wooledge.org/BashGuide(以及位于同一wiki上的BashFAQ和其他页面)。这些资源由freenode#bash频道中的人员主动维护,他们(虽然有时很刺眼)倾向于深切关注准确性和最佳实践。 –