Verzögerte Erweiterung

Verzögerte Erweiterung

Ich möchte ein Quine-SH-Skript erstellen und das habe ich bisher gemacht
quine.sh::

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

Konzentrieren Sie sich auf diese Zeile:

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

Beim ersten Vorkommen von $q(in \nq=$q) möchte ich zuerst den Rest der Variable setzen und dann diesen Teil (irgendeine Zeile setlocal enabledelayedexpansionin Batchdateien).Beachten Sie, dass ich eine Lösung für möchte sh, nicht für bashoder etwas anderes, da ich Portabilität möchte. Geben Sie mir auch keine Tipps, wie ich meinen Code kürzer machen kann usw. Ich möchte nur eine Lösung für das oben genannte Problem.

Antwort1

Wenn wir den Anfangsstring in 's statt in s einschließen , wird "er nicht sofort erweitert. Wir können ihn dann später erweitern mit :$qeval

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

Leider \nwird das nicht erweitert, die 's und "s gehen verloren und aus dem \"s wird ein "s.

Ausgabe:

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

Wir sind ziemlich nah dran, aber der Versuch, das Entkommen zu beheben, sederweist sich letztendlich als ziemlich mühselig.


Der Link von jw013 empfiehlt einen ziemlich verständlichen Ansatz:

  • Teil 1: Definieren Sie einige Daten (z. B. eine Variable), die den zweiten Teil des Programms enthalten
  • Teil 2: Verwenden Sie die Daten, um den ersten Teil des Programms auszugeben, und verwenden Sie die Daten dann, um den zweiten Teil des Programms auszugeben. (Behandeln Sie hier das für Teil 1 erforderliche Umbrechen und Escapen.)

Hier ist ein erster, grober Versuch hierzu:

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

Ausgabe:

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

Dieser Versuch leidet darunter, dass \nimmer interpretiert wird und die \s verloren gehen. Wir brauchen eine Möglichkeit, den Datenstring zu escapen, wenn wir ihn erneut drucken.


Hier ist eine Verbesserung, die mehrere Aufrufe verwendet, echoum die Probleme mit \ns zu vermeiden.

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

Es weist einen winzigen, schwer zu behebenden Fehler auf: 'In der Ausgabe (in der Mitte echo) fehlen s:

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

Das ist alles, was ich für Sie habe. Einige Ansatzpunkte zum Entkommen von Problemen. Viel Glück!

verwandte Informationen