我想製作一個 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"
這就是我為你準備的一切。一些逃避問題的起點。祝你好運!