Generated dollar-quote escape sequences are Bash-specific (in practice)
For the code
RUN apt-get update && \
apt-get -y install --no-install-recommends
… Bash-TPL generates:
printf "%s\n" RUN\ apt-get\ update\ \&\&\ \\
printf "%s\n" $'\tapt-get -y install --no-install-recommends'
Which prints
RUN apt-get update && \
$\tapt-get -y install --no-install-recommends
…when run with Dash.
As the readme says, the generated scripts are not supposed to use Bashisms.
The shell scripts that Bash-TPL generates are not intended to be Bash-specific.
The feature in question is, as far as I can tell, part of POSIX 2024, but it’ll be a while until support for it is added to all shells. Dash has committed a patch that adds it just a few hours ago.
I’m not sure whether it’s worth fixing it, but I guess this behavior should be at least documented here on the bug tracker.
Greetings @0xEAB !
Looking into a bit more, i think the issue is that I use %s as the formatter, when I should probably be using %b
Paste this into your DASH shell:
swap %s with %b
printf "%b\n" RUN\ apt-get\ update\ \&\&\ \\
printf "%b\n" $'\tapt-get -y install --no-install-recommends'
%b does appear to be a standard for posix printf:
- https://www.unix.com/man-page/posix/1posix/printf/
... An additional conversion specifier character, b , shall be supported as follows. The argument shall be taken to be a string that may contain backslash-escape sequences
It appears that many shells treat %s and %b similarly, which is likely why I didn't discover the issue earlier.
This fix is simple, but would technically be a breaking change ...
Just the same I'll put a PR together as it seems like the right thing to do.
If you want to test it out, I believe the change will be: before: line 560
if [ -n "${args}" ]; then
printf -v stmt "printf \"%%s\\\\n\" %s" "${args}"
else
printf -v stmt "printf \"\\\\n\""
fi
after
if [ -n "${args}" ]; then
printf -v stmt "printf \"%%b\\\\n\" %s" "${args}"
else
printf -v stmt "printf \"\\\\n\""
fi
Feel free to give that a try, and I'll also msg you when the PR is up in case you want to take a test drive before merging.
Thanks for using my project and taking the time to submit an issue!
Running
printf "%b\n" RUN\ apt-get\ update\ \&\&\ \\ printf "%b\n" $'\tapt-get -y install --no-install-recommends'
… with Dash 0.5.12-2 (Debian) prints:
RUN apt-get update && \
$ apt-get -y install --no-install-recommends
This however seems to work:
$ printf "%b\n" '\tapt-get -y install --no-install-recommends'
apt-get -y install --no-install-recommends
Ugh, you're right - I didn't notice the $ at the start of the line when I tested that :(
OK so I see now that I didn't need %b previously because $'...' is rather equivalent, ie expands escape sequences ...
I think I'll need to find a posix friendly function I can add to the file and call instead of printf %q to escape my strings ...
I'll look into and let you know what I find - Please also share any further research you may do on the matter.
I'm going to leave this issue open but close the MR ...