eval eval \''n='\''{1..'$(dc -e 1000vp)'}'\'' eval eval eval echo '\'\\\\\\\\\\\\\\\'\\\\\\\'\\\'\''$(('\'\\\'\\\\\\\'\\\'\''$n'\'\\\'\\\\\\\'\\\'\''*'\'\\\'\\\\\\\'\\\\\\\\\\\\\\\'\\\'\''{2..$((1000/n))}'\'\\\'\\\\\\\\\\\\\\\'\\\\\\\'\\\'\''))'\'\\\'\\\\\\\'\\\\\\\\\\\\\\\'\'';'\' | tr ' ' \\n | sort -n | uniq -u
打印最高1k的素数!它是如何工作的?为什么这么多反斜杠\
?
答案 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