我想制作一个 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"
这就是我为你准备的一切。一些逃避问题的起点。祝你好运!