bash quote escaping change in 4.4
bash -c "/tmp/printargs \\"abc\\""
Does not escape what you think it does. A backslash-backslash is an escaped backslash, handled by the calling shell — so that is the same as running:
/tmp/printargs \abc\
because the double-quotes are not escaped. You could have just written:
bash -c '/tmp/printargs \abc\'
I'm guessing you actually wanted:
bash -c "/tmp/printargs \"abc\""
which escapes the double quotes, passing a quoted "abc" to the bash -c.
(I'm guessing the different behavior you're seeing is different versions of bash handling the escaped nothing at end of input differently.)
Perl version of printargs (slightly improved behavior):
#!/usr/bin/perl
use feature qw(say);
for (my $i = 0; $i < @ARGV; ++$i) {
say "$i: |$ARGV[$i]|";
}
bash -c "/tmp/printargs \\"abc\\""
Are you sure this is what you want to do? If you run that with set -x
in effect, you'll see that the command that runs, is
bash -c '/tmp/printargs \abc\'
i.e. you're passing the shell a string that ends in a backslash. Your first quoted string contains an escaped backslash, then you have an unquoted abc
, an escaped backslash, and then an empty quoted string. (Note how the syntax highlighting done by Stackexchange shows the abc
is not quoted.)
The unquoted backslash at the end of input doesn't make much sense. A backslash either escapes the following character, or starts a continuation line, where it's deleted along with the following newline, like here:
$ bash -c $'echo "foo\\\nbar"'
foobar
This case has neither. You're possibly trying to do either of these:
bash -c "/tmp/printargs \"abc\""
bash -c '/tmp/printargs "abc"'
Both of which produce the output ARG |abc|
.
We can see the difference between shells with a bit simpler test:
$ bash -c 'echo $BASH_VERSION; echo abc\'
4.4.12(1)-release
abc\
$ ./bash -c 'echo $BASH_VERSION; echo abc\'
4.3.30(1)-release
abc
$ dpkg -l dash |grep ^i
ii dash 0.5.8-2.4 amd64 POSIX-compliant shell
$ dash -c 'echo abc\'
abc\
$ dpkg -l zsh |grep ^i
ii zsh 5.3.1-4+b2 amd64 shell with lots of features
$ zsh -c 'echo abc\'
abc
If I had to guess, I'd start looking for the source of the change in this change:
This document details the changes between this version, bash-4.4-alpha, and the previous version, bash-4.3-release. 1. Changes to Bash cccc. Fixed a bug that resulted in short-circuited evaluation when reading commands from a string ending in an unquoted backslash, or when sourcing a file that ends with an unquoted backslash.