EXECLINE-SUBSTITUTE(7)
๐ execline-substitute(7) ๐
ok so first things first, bestie: this is EXECLINE-SUBSTITUTE(7), from the Miscellaneous Information Manual, and it's literally the whole vibe guide to execline variable substitution. come learn with me ๐ซถ
โจ NAME โจ
execline-substitute โ the big-picture overview of execline variable substitution. like, the concept, not one single command. slay.
๐ธ DESCRIPTION ๐ธ
ok so picture this: in a shell, when you type
$ A='foobar' ; echo $A
the echo(1) command gets handed the argument foobar. the foobar value got substituted in place of the A variable. iconic behaviour honestly.
now here's the twist ๐ โ execline keeps no state, so it has no real variables at all. but it still gives you that substitution facility, through substitution commands, namely:
a substitution command takes a key โ that's a string, and it can contain any character except $, { and }, though ngl it's recommended you stick to only alphanumerical characters โ plus a way to compute a value.
๐ผ Basics ๐ผ
if the substitution key is foo, then the substitution command is gonna look for every occurrence of ${foo} or $foo in the rest of its argv. heads up: ${foo}bar matches, but $foobar does not. so to be safe, always use the brace syntax unless $foo is a word all on its own. fr fr.
every match then gets replaced with the value. ๐ซ
the simplest example is this:
#!/command/execlineb
define FOO blah
echo $FOO
which replaces the FOO key with the blah value, then executes the echo(1) command. so that script prints blah on stdout. easy!
๐ Quoting ๐
execline lets you write literal ${foo} constructs even while the foo variable is actively being substituted โ that's the quoting mechanism doing its thing. brace (pun fully intended ๐
) yourself: this next bit is the most complex part of the entire language. no cap.
Rationale
if we want to be able to have a literal ${foo}, then:
- the
${foo}sequence has to mean one of two things: be substituted, or don't be substituted. - the default (unquoted) action should be: substitute.
- a sequence that means "do not substitute" should be able to appear literally. and the quote character should also be able to appear literally before a sequence that means "substitute". (tricky, eh? ๐ญ)
- there should be as few quote characters as possible, to dodge all those shell-like quoting nightmares.
Syntax
the rule, bestie:
- the backslash (
\) is a quote character for substitution commands. - the following rule applies only if the
fookey is explicitly used in a substitution command. if no command tries to substitute anything forfoo, sequences like${foo}and any preceding backslashes are left completely untouched. - (Substitute.) if
${foo}is preceded by2*nbackslashes (an even number), the whole sequence gets replaced withnbackslashes, followed by the substituted value. - (Do not substitute.) if
${foo}is preceded by2*n+1backslashes (an odd number), the whole sequence gets replaced withnbackslashes, followed by the literal${foo}.
and now the catch ๐ซ โ the execlineb(1) launcher, same as the shell, interprets backslashes as escape characters. so to make a word containing a backslash, you need to write two backslashes in your execline script or shell command line. which means the whole number of backslashes you write before your ${foo} sequence must be doubled so the substitution command reads the proper number of backslashes and does its job correctly.
once you keep that in mind, the quoting rule is honestly logical. i promise. ๐
Example
the quoting rule is best illustrated with this example, where the A key is substituted and the $B sequences mean nothing special:
#!/command/execlineb
define A val
foreground { echo $A \\$A \\\\$A \\\\\\$A \\\\\\\\$A \\\\\\\\\\$A }
echo $B \\$B \\\\$B \\\\\\$B \\\\\\\\$B \\\\\\\\\\$B
prints
val $A \val \$A \\val \\$A
$B \$B \\$B \\\$B \\\\$B \\\\\$B
phew. ๐ฎโ๐จ
๐ฆ Value transformations ๐ฆ
a value can go through several transformations before it gets substituted. it can be crunched, chomped, and/or split (cf. execline-transform(7)).
๐ Substitution of split values ๐
a 'split' value for FOO means a word containing ${FOO} will be replaced by zero, one, or (usually) more than one word. the value actually means a list of values.
the rule is: substituting a list of values (v1, v2, ...) for a key A is the same as listing the substitutions of every value vi for A.
for instance,
#!/command/execlineb
define -s FOO "v1 v2 v3" echo prefix-${FOO}-postfix
will substitute three values for $FOO: v1, v2 and v3. so the echo(1) command gets called with three arguments: prefix-v1-postfix, prefix-v2-postfix, and prefix-v3-postfix. chef's kiss ๐
(implementation note, and this one's important: the fact that word prefixes are kept is exactly what makes execline's substitutions secure. blocks (cf. execline-block(7)) are implemented via prefix space characters; a substitution happening inside a block will always produce words beginning with the right amount of spaces, so substituted values can't prematurely terminate a block. ๐ฅ)
Recursive substitutions
a direct consequence of that rule: substitutions get performed recursively if more than one key appears in a single word and the values for those keys are split. parallel substitutions are performed left to right. for instance, in
#!/command/execlineb
define -s B "1 2 3" echo ${B}x${B}
the ${B}x${B} word gets replaced with nine words: 1x1, 1x2, 1x3, 2x1, 2x2, 2x3, 3x1, 3x2, and 3x3, in that order.
here's one with two distinct substitutions running in parallel:
#!/command/execlineb
multisubstitute
{
define -s A "a b c d"
define -s B "1 2 3"
}
echo ${A}x${B}
the ${A}x${B} word gets replaced with twelve words: ax1, ax2, ax3, bx1, bx2, bx3, cx1, cx2, cx3, dx1, dx2, and dx3, in that order. you can check for yourself that the order of the define directives in multisubstitute(1) does not matter. ๐ซ
if that left-to-right order doesn't suit you, then you should perform serial substitutions. for instance, the previous script can be replaced with
#!/command/execlineb
define -s B "1 2 3"
define -s A "a b c d"
echo ${A}x${B}
and that will substitute ${B} first, then ${A}. so it prints
ax1 bx1 cx1 dx1 ax2 bx2 cx2 dx2 ax3 bx3 cx3 dx3
in that order. ๐ฏ
๐ Not for the faint of heart ๐
if you think you've mastered the art of execline substitution, then you can try to do better than these people:
- Joรซl Riou [1] wrote the first
execlinebquine [2], using onlyecho(1)as a non-execline external command. - shortly after, Paul Jarc [3] wrote a much shorter quine [4], using
echo(1)andenv(1)as non-execline external commands. he also wrote a revised version [5], using onlyecho(1), and a shorter definitive version [6]. that last one is probably very close to the shortest possible execline quine. - David Madore [7] wrote another quine [8], using
printf(1). his quine is longer than the other ones, but it's well-commented and can be used as a tutorial on how to write quines. :)
๐ SEE ALSO ๐
define(1), echo(1), elgetpositionals(1), elglob(1), env(1), execlineb(1), importas(1), multidefine(1), multisubstitute(1), multisubstitute(1), printf(1), execline-block(7), execline-transform(7)
(yes, multisubstitute(1) is listed twice in the original โ that's just how it is, i don't make the rules ๐
)
- [1]
http://jriou.org/ - [2]
https://skarnet.org/software/execline/quine-jriou.txt - [3]
https://code.dogmap.org/ - [4]
https://skarnet.org/software/execline/quine-prj.txt - [5]
https://skarnet.org/software/execline/quine-prj-2.txt - [6]
https://skarnet.org/software/execline/quine-prj-3.txt - [7]
http://www.madore.org/~david/ - [8]
https://skarnet.org/software/execline/quine-dam.txt
this man page is ported from the authoritative documentation at: https://skarnet.org/software/execline/el_substitute.html
๐ AUTHORS ๐
Laurent Bercot Alexis <flexibeast@gmail.com> (man page port)
ok and that's the whole page, bestie, you ate it ๐
bye bye, go substitute some values responsibly!! ๐โจ this cutie came from Debian, dated April 16, 2024, and it's the one and only EXECLINE-SUBSTITUTE(7) from the Miscellaneous Information Manual โ see you in the next man page, mwah ๐๐
๐ฆ where this page comes from
- nixpkgs unstable: execline 2.9.9.2
- nixpkgs unstable: execline-man-pages 2.9.9.1.1
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms