在分析 TLDP 的脚本网页,提供如下代码进行分析:
export SUM=0
for f in $(find src -name "*.java"); do
export SUM=$(($SUM + $(wc -l $f | awk '{ print $1 }')))
done
echo $SUM
据我了解,它计算目录中所有 *.java 文件的行数总和src
。我不明白的是使用关键字的原因export
,即如此描述:
导出命令使变量可供正在运行的脚本或 shell 的所有子进程使用。
既然SUM
子进程永远不会访问它,那么有什么理由导出它呢?
答案1
据我了解,它计算目录 src 中所有 *.java 文件的行数总和。
这不一定完全正确。它计算*.java
以目录树为根的所有文件src
(即src
及其所有子目录)的行数总和。但对于任何包含空格的文件路径或目录名称以.java
.
由于 SUM 永远不会被子进程访问,是否有任何理由导出它?
不。
我可能会编写这样的代码片段,使其在此过程中文件名安全:
find src -type f -name '*.java' -exec wc -l {} \; | awk '{ s += $1 } END { print s }'
更好的解决方案可能是这样的:
find src -type f -name '*.java' -exec cat {} + | wc -l
答案2
你说得对,这里没有必要使用export
。但这段代码还有更多问题:
$ ~/.cabal/bin/shellcheck e.sh
In e.sh line 4:
for f in $(find src -name "*.java"); do
^------------------------^ SC2044: For loops over find output are fragile. Use find -exec or a while read loop.
In e.sh line 5:
export SUM=$(($SUM + $(wc -l $f | awk '{ print $1 }')))
^--^ SC2004: $/${} is unnecessary on arithmetic variables.
^-- SC2086: Double quote to prevent globbing and word splitting.
Did you mean:
export SUM=$(($SUM + $(wc -l "$f" | awk '{ print $1 }')))
For more information:
https://www.shellcheck.net/wiki/SC2044 -- For loops over find output are fr...
https://www.shellcheck.net/wiki/SC2086 -- Double quote to prevent globbing ...
https://www.shellcheck.net/wiki/SC2004 -- $/${} is unnecessary on arithmeti...
在脚本中使用小写变量名称是一个很好的做法,请参阅 这 以获得解释。
一般来说,不推荐tldp.org,参见 这或者 这。我还看到人们在 StackExchange 上不推荐 tldp.org。