延迟扩张

延迟扩张

我想制作一个 quine .sh 脚本,这就是我到目前为止所做的
quine.sh::

#!/bin/sh
q="#!/bin/sh\nq=$q;echo \$q";echo $q

重点关注这一行:

q="#!/bin/sh\nq=$q;echo \$q";echo $q

$q(in \nq=$q) 第一次出现时,我首先要设置变量的其余部分,然后设置这部分(setlocal enabledelayedexpansion批处理文件中的某行)。sh请注意,我想要一个、 notbash或其他东西的解决方案,因为我想要可移植性。另外,不要给我关于如何使我的代码更短等的提示。我只想要上述问题的解决方案。

答案1

如果我们将初始字符串包裹在's 而不是"s 中,则$q不会立即展开。然后我们可以稍后使用以下方法扩展它eval

#!/bin/sh
q='#!/bin/sh\nq=$q;eval "echo \"\$q\""';eval "echo \"$q\""

不幸的是,\n没有扩展,'s 和"s 丢失,\"s 变成"s。

输出:

#!/bin/sh\nq=#!/bin/sh\nq=$q;eval "echo \"\$q\"";eval echo "$q"

我们已经非常接近了,但是尝试解决转义问题sed最终变得相当麻烦。


jw013 的链接推荐了一种相当容易理解的方法:

  • 第 1 部分:定义一些包含程序第二部分的数据(例如变量)
  • 第2部分:使用数据输出程序的第一部分,然后使用数据输出程序的第二部分。 (此处处理第 1 部分所需的包装和转义。)

这是初步的粗略尝试:

#!/bin/sh
data="echo -e \"#!/bin/sh\ndata=\"\$data\"\"\\n\$data"
echo -e "#!/bin/sh\ndata=\"$data\"\n$data"

输出:

#!/bin/sh
data="echo -e "#!/bin/sh
data="$data""
$data"
echo -e "#!/bin/sh
data="$data""
$data

这种尝试因\n总是被解释而\s 丢失而受到影响。当我们再次打印数据字符串时,我们需要某种方法来转义它。


这是一项改进,它使用多次调用echo来避免 s 的问题\n

#!/bin/sh
data='echo "#!/bin/sh"\necho "data=$data"\necho -e "$data"'
echo "#!/bin/sh"
echo "data='$data'"
echo -e "$data"

它有一个难以克服的小缺陷,即'输出中缺少 s(中间echo):

#!/bin/sh
data='echo "#!/bin/sh"\necho "data=$data"\necho -e "$data"'
echo "#!/bin/sh"
echo "data=$data"
echo -e "$data"

这就是我为你准备的一切。一些逃避问题的起点。祝你好运!

相关内容