延遲擴張

延遲擴張

我想製作一個 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"

這就是我為你準備的一切。一些逃避問題的起點。祝你好運!

相關內容