A quine in sed
2019-04-01 / 2 mins read
Yesterday someone on IRC corrected their typos with classic sed-like replaces1, and for some reason that got me wondering if you can write a quine in sed.
Of course you can.
|
When run in dash
or zsh
(but not bash
2), the output is that same line. That's what quines are: self-replicating programs. For a thorough review, see David Madore's excellent page about quines.
Dissection
Like many quines, this one consists of a data part and a stream manipulation part. That's necessary to use sed in the first place. However, the escaping mechanism of the shell also plays a large part, so strictly speaking this is a POSIX shell quine that uses echo
and sed
.
The data part is what is echoed and piped to sed. The sed command run on the input is this:
This combines three regex replace commands:
s/\\\\/&&&&/g
s/\"/\\\\&/g
s/.*/echo \"&\" | sed \"&\"/
The third one is really the only interesting part: take the input, and basically print echo <input> | sed <input>
. Figuring out that part is easy; finding a way to work with character escaping such that the input data can be crafted properly is a bit more time-consuming.
I tried finding a smart way of combining '
, "
, \x22
and such, but that turned out to be difficult. Working with the shell escaping mechanism instead of avoiding it was a better idea. Just find a way to escape special characters before printing. Then write the program as data. Voila, the quine is ready.
|
|
Example: I canot spell
-> s/n/nn/
I tried with bash, too. It works with echo "s/\\\\/&&/g;s/\"/\\\\&/g;s/.*/echo \"&\" | sed \"&\"/" | sed "s/\\\\/&&/g;s/\"/\\\\&/g;s/.*/echo \"&\" | sed \"&\"/"
. There's probably some escaping setting that affects this but I didn't take the time to find it.