我是一名bash初学者,正在阅读书籍和手册以进一步学习。我在一本书中发现了以下脚本,它计算总大小并展示了命令替换的用法。我不理解包含
乍一看,它看起来像一个数组,但这里的操作符
{totalsize:=0}
、{size:-0}
和{totalsize-unset}
的部分。请问有人可以解释一下吗?乍一看,它看起来像一个数组,但这里的操作符
:=
和:-
是干什么的?totalsize
是包含值的变量,但是当我运行echo ${totalsize-unset}
时,它确实返回了PWD中文件大小的总和。这个-unset
是一种内置的东西吗?$ while read perms links owner group size month day time file
> do
> printf "%10d %s\n" "$size" "$file"
> totalsize=$(( ${totalsize:=0} + ${size:-0} ))
> done < <(ls -l *)
$ echo ${totalsize-unset}
a[$(...)]
的第五个字段,其中...
是任何命令,那么这个命令将被执行。不相信我?在你的目录中执行以下操作:touch $'\n_ _ _ _ a[$(echo>gniourf\ \'hello\ Donbhupi\')]'
。它会创建一个奇怪的文件名。无论如何,然后运行你的命令。你会发现你有一个新文件,叫做gniourf
,里面包含了一条消息。 - gniourf_gniourf\n
将解析器发送到下一行,然后名称中的五个空格将其移动为“size”可读,并且剩下的内容无法作为数字打印,但是是什么使其作为命令执行的呢?如果将其作为整数传递给算术加法,那么它是某种数组脚本吗? 还有,@John1024在他的第一条评论中提供了有关解析“ls”的链接。 - Donbhupia=b b=c c=42; echo $((a))
将输出42
。为了好玩,您可以尝试a=b b=a; echo $((a))
或者甚至是a=a; echo $((a))
。现在来看数组:a=(); b='a[$(ls)]'; echo "b=$b"; echo "\$((b))=$((b))"
。这将执行ls
命令。这是因为 Bash 需要知道您正在使用哪个键,所以它尝试对其进行解引用... 但为此它会执行$(ls)
。 - gniourf_gniourfzcat $( ls -tr /var/log/apt/history.log*.gz )
:由于日志文件具有受控名称,所以它可能是可以接受的。在这种情况下,问题不在于任意代码执行,而在于路径名扩展和单词拆分:它只会破坏命令。但是,由于您相当确定文件具有受控名称,因此这是可以接受的。不过,您可以像这样强制执行检查:( shopt -s extglob failglob; zcat $(ls -tr /var/log/apt/history.log+([[:digit:]]).gz ) ; cat /var/log/apt/history.log ) | egrep '^Commandline:'
。 - gniourf_gniourf