A quine is something that, when evaluated, yields itself. More precisely, a quine is x
, such that when we evaluate, interpret, or otherwise run x
, we get x
as the result. Quines are interesting because their existence in a language points to the language’s self-referentiality.
Let’s work through building a quine in English (this is mostly lifted from “I am a Strange Loop” by Douglas Hofstadter). We start with a sentence fragment:
preceded by itself in quotes is a funny sentence
Obviously, the above is not a real sentence in English — “is” is missing its subject. Let’s try adding one; in fact, let’s try using the quotation of the above as the subject.
“preceded by itself in quotes is a funny sentence” preceded by itself in quotes is a funny sentence
This is a full English sentence and we can interpret its meaning. We see it says that something is a funny sentence. What is that something? It’s the content of the quotation, “preceded by itself in quotes”, namely:
“preceded by itself in quotes is a funny sentence” preceded by itself in quotes is a funny sentence
But this is the sentence we started with! So, we built a sentence that says that a sentence, which happens to be itself, is a funny one. In other words, we built a sentence that asserts that it is funny. This is a quine (technically, only the description part of the sentence is the quine, but interpreting the whole thing without a predicate is less fluent).
Now, let’s build a quine in Bash. The idea is the same as in English, but the structure is different: to accommodate the shebang, we first print a bit of code, then the quoted text, then a bit more code; we also need to be careful with quoting, so we save the single quote character in a variable.
#!/bin/bash
T='#!/bin/bash
Q=$(printf "\x27") # A literal single quote
echo "$T" | head -n2 -
echo T=$Q"$T"$Q
echo "$T" | tail -n6 -'
Q=$(printf "\x27") # A literal single quote
echo "$T" | head -n2 -
echo T=$Q"$T"$Q
echo "$T" | tail -n6 -
Just like with the English sentence fragment, the quoted text in the script is not a full script because the T
variable is undefined; it’s up to the middle echo
to fill it in.
To summarize, we’ve looked at quines, constructs that refer or evaluate to themselves, and we’ve seen how to construct them in English and Bash.
Note that, although we could get much shorter code by referencing the current script name, $0
, that wouldn’t be a quine since it uses facilities outside of the Bash language.