具有多重证据的这种陈述如何发挥作用?

时间:2018-06-17 20:21:18

标签: linux bash

eval eval \''n='\''{1..'$(dc -e 1000vp)'}'\'' eval eval eval echo '\'\\\\\\\\\\\\\\\'\\\\\\\'\\\'\''$(('\'\\\'\\\\\\\'\\\'\''$n'\'\\\'\\\\\\\'\\\'\''*'\'\\\'\\\\\\\'\\\\\\\\\\\\\\\'\\\'\''{2..$((1000/n))}'\'\\\'\\\\\\\\\\\\\\\'\\\\\\\'\\\'\''))'\'\\\'\\\\\\\'\\\\\\\\\\\\\\\'\'';'\' | tr ' ' \\n | sort -n | uniq -u

打印最高1k的素数!它是如何工作的?为什么这么多反斜杠\

1 个答案:

答案 0 :(得分:4)

预赛

eval是一个执行其字符串参数的命令,就像您自己直接在控制台中键入它一样。

如果要在bash中指定文字字符串',可以将其双引号"'"或将其\'转义。不带引号的\'被解释为'

如果要在bash中指定文字字符串\,可以引用它'\'或将其\\转义。不带引号的\\被解释为\

由于提到的转义机制,每个eval可以反转一半的反斜杠。以下每个命令只打印一个\

echo \\
eval echo \\\\
eval eval echo \\\\\\\\

因为命令中有很多eval s,所以还有很多反斜杠。

未加引号的{1..3}已扩展为1 2 3。组合多个{..}生成笛卡尔积:echo a{1..3}b{8..9}c打印 a1b8c a1b9c a2b8c a2b9c a3b8c a3b9c

分析

乘法表

第一个管道|之前的部分生成一个乘法表,其中所有数字都来自区间[2,1000]。运行稍微更改的命令以自己查看乘法表:

eval eval \''n='\''{1..'$(dc -e 1000vp)'}'\'' eval eval eval echo '\'\\\\\\\\\\\\\\\'\\\\\\\'\\\'\''$(('\'\\\'\\\\\\\'\\\'\''$n'\'\\\'\\\\\\\'\\\'\''*'\'\\\'\\\\\\\'\\\\\\\\\\\\\\\'\\\'\''{2..$((1000/n))}'\'\\\'\\\\\\\\\\\\\\\'\\\\\\\'\\\'\''))'\'\\\'\\\\\\\'\\\\\\\\\\\\\\\'\'';'\' | less -S

Bash扩展$(dc -e 1000vp),它计算1000的平方根,即(已放置)31。

{1..31}已分配给变量n供以后使用。到目前为止,{1..31}只是一个文字字符串。稍后进行扩展,以生成另一个{...}的笛卡尔积。

在命令的深处,引用了$((... * ...))。对...中的每个数字,$n替换为'{1..31}'(值'{2..'$((1000/n))'}')和n。 还有一些eval将此扩展为

echo "$((1*2)) $((1*3)) $((1*4)) ... $((1*1000))
      $((2*2)) $((2*3)) ... $((2*500))
      ...
      $((31*2)) ... $((31*32))"

然后扩展到最终的乘法表。

使用乘法表获取素数

如果乘法表中的数字多次出现,那么该数字的除数多于自身和一个除数,这意味着它是非素数。因此,选择表中的所有唯一编号。这是用成语

完成的
echo "... multiplication table ..." | tr ' ' \\n | sort -n | uniq -u