奇怪的bash范围规则使我望而却步

Bit*_*nce 4 bash sum

考虑:

t=0 ; for i in 1 2 3 4 5 6 7 8 9 10 ; do t=$((t+i)) ; done ; echo $t
Run Code Online (Sandbox Code Playgroud)

打印55.

但:

totsize=0
find /home/user -type f -mmin -4860 -a -mmin +3420 | xargs du | \
while read size rest ; do
    totsize=$((totsize+size))
    echo "$totsize"
done
echo "Sum: $totsize kb"
Run Code Online (Sandbox Code Playgroud)

即使临时打印语句打印一个合理的总和,也打印"Sum:0 kb".

我知道我之前遇到过这个问题,但从未理解过.有什么区别?

seh*_*ehe 8

totsize=0

while read size rest ; do
    totsize=$((totsize+size))
    echo "$totsize"
done < <(find /home/user -type f -mmin -4860 -a -mmin +3420 | xargs du)
echo "Sum: $totsize kb"
Run Code Online (Sandbox Code Playgroud)

防止子shell,因为子shell会限制范围 totsize


多花几句话:

do_something < <(subprocess)
Run Code Online (Sandbox Code Playgroud)
  • 将在主shell中运行do_something(这是带有进程替换的输入重定向)

.

subprocess | do_something
Run Code Online (Sandbox Code Playgroud)
  • 将在单独的(子)shell中运行do_something(这是一个管道子进程)


kur*_*umi 6

这是因为管道创建了一个子shell,因此totsize在子shell中是"本地的".你可以尝试这个(bash)

totsize=0
while read size rest ; do
    totsize=$((totsize+size))
    echo "$totsize"
done < <(find /home/user -type f -mmin -4860 -a -mmin +3420 | xargs du)
echo "Sum: $totsize kb"
Run Code Online (Sandbox Code Playgroud)

或者不是使用bash,而是打电话 awk

$> find /home/user -type f -mmin -4860 -a -mmin +3420 | xargs du | awk  '{s+=$1}END{print "total size: "s}'
Run Code Online (Sandbox Code Playgroud)

但是你确定你想要使用du没有任何选项,因为大小不是"准确"(使用du -b会更好).如果你有GNU查找,你可以使用-printf

find /home/user -type f -mmin -4860 -a -mmin +3420 -printf "%s\n" | awk  '{s+=$1}END{print "total size: "s" bytes"}'
Run Code Online (Sandbox Code Playgroud)