tenticle

Humbling Experience

Posted on 2024-01-31 by xkollar in Bash, Fun.

I’m relatively comfortable with Bash but when the other day I saw this Stack Overflow answer on how to decode URL-encoded string in shell my brain took a moment to process it.

What?

Let me copy it here just to appreciate it.

function urldecode() { : "${*//+/ }"; echo -e "${_//%/\\x}"; }

Let’s explore what is going on here, looking at it in an easier-to-digest(?) form:

function urldecode() {
    : "${*//+/ }"
    echo -e "${_//%/\\x}"
}

First part is using builtin : with the (single) argument being expansion of all the function’s arguments into a single string "${*}" while replacing all the occurrences of + with space (double-forward-slash pattern substitution).

Confusing part is that : builtin kinda does nothing (except for exiting with 0; many of you have probably invoked a spell of shape while :; do something; done or used it as a part of comment/documentation when combined with here document). While this looks like a nop/pass/… it is not.

The magic is revealed when we inspect the following line where special variable ${_} is used. From Bash documentation, in this case it

expands to the last argument to the previous simple command executed in the foreground, after expansion.

Therefore the purpose of the previous line was “just” to set ${_}. There all the percent signs get replaced with \x (double backslash for escaping in ") and pass that to echo -e for evaluation.

Obviously, people who read me know there is a bug: urldecode -e will return nothing. It is still very elegant way to solve task at hand on command line. Easy fix with printf '%b'.

function urldecode() { : "${*//+/ }"; printf %b "${_//%/\\x}"; }