3 added 566 characters in body
source | link
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)unquoted backslash at the end of input doesn't make much sense. Unquoted, itA 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.

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.

The (unquoted) backslash at the end of input doesn't make much sense. Unquoted, it either escapes the following character, or starts a continuation line, where it's deleted along with the following newline:

$ 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
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.

2 added 566 characters in body
source | link
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.

The (unquoted) backslash at the end of input doesn't make much sense. Unquoted, it either escapes the following character, or starts a continuation line, where it's deleted along with the following newline:

$ 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
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.

The (unquoted) backslash at the end of input doesn't make much sense. Unquoted, it either escapes the following character, or starts a continuation line, where it's deleted along with the following newline:

$ 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|.

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.

The (unquoted) backslash at the end of input doesn't make much sense. Unquoted, it either escapes the following character, or starts a continuation line, where it's deleted along with the following newline:

$ 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
1
source | link

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.

The (unquoted) backslash at the end of input doesn't make much sense. Unquoted, it either escapes the following character, or starts a continuation line, where it's deleted along with the following newline:

$ 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|.