[...there doesn't seem to be a separate M4SH list, apologies if this needs to go elsewhere...]
(problem I'm actually trying to solve in case this is an A/B thing): I have an m4sh script. (I want portable, but also care about it not being slower than it has to be) Some previous run of configure has already figured out the best shell to use, etc, and I just want ./configure to be writing that into the #! line so that we don't have to redo that test and fork every time my script runs, because my script is going to be run A LOT. (... and that if we were worried about missing out on new and better shells being installed later, presumably one would want to be re-running configure on every change to the build environment anyway...) The obvious thing to do and what I suspect was intended by the m4sh authors, otherwise why bother exposing the BINSH diversion? is this (autom4te -l m4sh - | head) AS_INIT m4_cleardivert([BINSH])dnl m4_divert_text([BINSH],[@%:@!@BEST_SHELL@])dnl the point of this being to put #!@BEST_SHELL@ on the first line of myscript.in. But instead (as of v.69), I get this: #!/bin/sh #!@BEST_SHELL@ The problem, I believe, is that, under the hood, BINSH is actually diversion 0, which M4 gives special treatment: Everything sent there gets output immediately (because you can't have negative diversions getting in front of it, so why not?), so that once AS_INIT writes the #!/bin/sh line, it's a done deal. The subsequent m4_cleardivert() call has nothing to clear. workaround #1: m4_divert()[@%:@!@BEST_SHELL@ @%:@ Please pretend this is not here: ]m4_divert([KILL])dnl AS_INIT is annoying because of the superfluous #! line workaround #2: m4_copy_force([_m4_divert(KILL)], [_m4_divert(BINSH)])dnl AS_INIT m4_divert_text([],[@%:@!@BEST_SHELL@])dnl to keep AS_INIT from writing that first line is probably venturing into the realm of Asking For Trouble in its use of private/internal stuff (even if _m4_divert is used pervasively enough in m4sugar|m4sh to be unlikely to *ever* be repurposed...). Suffice it to say, I'm not happy about either of these. It seems to me, the fundamental mistake is that none of M4sugar, M4sh, Autoconf, should EVER be using diversion 0 (there's no reason to; everything sent to non-negative diversions is going to make it out the door eventually) and that this patch: --- m4sugar/m4sh.m4 2020-12-25 01:25:29.000000000 -0800 +++ - 2022-09-17 14:35:23.095083010 -0700 @@ -59,13 +59,13 @@ # DIVERSION-NAME which is supposed to be an actual diversion number. # Of course it would be nicer to use m4_case here, instead of zillions # of little macros, but it then takes twice longer to run `autoconf'! -m4_define([_m4_divert(BINSH)], 0) -m4_define([_m4_divert(HEADER-REVISION)], 1) -m4_define([_m4_divert(HEADER-COMMENT)], 2) -m4_define([_m4_divert(HEADER-COPYRIGHT)], 3) -m4_define([_m4_divert(M4SH-SANITIZE)], 4) -m4_define([_m4_divert(M4SH-INIT-FN)], 5) -m4_define([_m4_divert(M4SH-INIT)], 6) +m4_define([_m4_divert(BINSH)], 1) +m4_define([_m4_divert(HEADER-REVISION)], 3) +m4_define([_m4_divert(HEADER-COMMENT)], 4) +m4_define([_m4_divert(HEADER-COPYRIGHT)], 5) +m4_define([_m4_divert(M4SH-SANITIZE)], 6) +m4_define([_m4_divert(M4SH-INIT-FN)], 7) +m4_define([_m4_divert(M4SH-INIT)], 8) m4_define([_m4_divert(BODY)], 1000) is What You Want, leaves space after BINSH and before the first Autoconf diversion (10) which are the most likely places that Future You will want to add stuff, and, in theory, since nobody's supposed be referring to diversion numbers directly anyway, if this breaks anything it'll be Their Own Damn Fault. On the other hand, unless I'm doing something horribly wrong/misguided in wanting to change the shell, I find it hard to believe this is the first time this problem has come up. Meaning what do people actually do here? Is there some common idiom already? If so, it would be worth mentioning this in the M4sh Manual. Barring that, I suppose the safest way out of this box, given that people out there probably *are* doing strange shit with diversions, would be to give AS_INIT some kind of "Don't Write The #! Line" flag, making the user responsible for writing to BINSH herself. But that might be deemed inelegant. Or is there something else I'm missing? (*) If not, then please consider this a feature request, (any of the above patch, the idiom-mention in the manual, or the AS_INIT option,...) Thanks. (*) I know about AS_INIT_GENERATED for making shell scripts that run after ./configure. However that seems to be tailored for creating config.status, which I'm guessing is the only thing currently that uses it. If I do an AS_INIT_GENERATED as part of AC_CONFIG_COMMANDS, that seems to dump lots of autoconf baggage at the front of my script, e.g., preparations for every shell function that configure.ac/config.status needs that my script dosn't. And if I write my own configure-time script that initializes with AS_INIT and then uses AS_INIT_GENERATED to generate the script I care about, I seem to be get the exact same output as when I have my script do AS_INIT directly, i.e., all of the configure-time testing (e.g., which shell? let's feed thousands of characters to echo and see if it breaks? etc) that I want to skip in later runs of my script ends up there anyway. ... also seems to me the Autotest folks should care about this but they seem to have punted on this problem. -- Roger Crew c...@cs.stanford.edu, w...@cpan.org 206.940.5732