#538100 dash built-in echo expands \nnn sequences

Package:
dash
Source:
dash
Description:
POSIX-compliant shell
Submitter:
Christoph Anton Mitterer
Date:
2023-02-26 18:51:03 UTC
Severity:
wishlist
Tags:
#538100#5
Date:
2009-07-23 01:25:56 UTC
From:
To:
Hi.

I've made some scripts where I pre-process an arbitrary file name for
some sed- and grep expressions.
As e.g. . and / (which can occur in filenames) may have special
meaning to sed and grep, I quote the each character of the filename
with \ before using it further.

I do about this:
file='./data/image.oga'
echo $file
echo "$file"

file_entry_quoted="$( printf "${file}" | sed --regexp-extended
's/(.)/\\\1/g' )"
echo $file_entry_quoted
echo "$file_entry_quoted"

under bash this gives me:
./data/image.oga
./data/image.oga
\.\/\d\a\t\a\/\i\m\a\g\e\.\o\g\a
\.\/\d\a\t\a\/\i\m\a\g\e\.\o\g\a

under dash I get:
./data/image.oga
./data/image.oga
\.\/\d	\/\i\m\g\e\.\o\g
\.\/\d	\/\i\m\g\e\.\o\g
(that's a tab after the d, the \a seem to be replaced by 0x7)


With the `` style of command substitution it's even "worse" in dash,...
file_entry_quoted="` printf "${file}" | sed --regexp-extended
's/(.)/\\\1/g' `"
In that case,.. each character is replaced by 0x1.

The \a and 0x1 thingy is strange anyway, isn't it?
But I'd even haven't expected that \t would be replaced as POSIX says
(http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_03):
"The results of command substitution shall not be processed for
further tilde expansion, parameter expansion, command substitution, or
arithmetic expansion. If a command substitution occurs inside
double-quotes, field splitting and pathname expansion shall not be
performed on the results of the substitution."

Or do I misunderstand something?


Another thing where bash and dash behave differently is:
fo='\\'
echo $fo
echo "$fo"

gives in bash:
\\
\\

in dash however:
\
\

Is this expected/desired?
Might be, as
http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06
says:
"Quote removal (see Quote Removal) shall always be performed last."
But then,.. this would be a grave incompatibility of bash with POSIX.


Thanks for your help :-),
Chris.
----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.

#538100#10
Date:
2009-07-23 01:36:33 UTC
From:
To:
Uhm... I've just noted:
http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_07

"The quote characters: '\', '", and '' (backslash, single-quote,
double-quote) that were present in the original word shall be removed
unless they have themselves been quoted."

=> "int the original word" => so does this mean that no additional quote
removal should happen on substituted parameter?


Chris.

#538100#15
Date:
2009-07-23 23:52:38 UTC
From:
To:
I've just noticed something even more weird....
When using that weird "\.\/\d	\/\i\m\g\e\.\o\g" string (with the tab and
the 0x7's) as grep pattern, it actually matches lines that contain
"./data/image.oga".
When using --color=auto one sees, that the full "./data/image.oga" is
matched, and not just the first characters or so.

Perhaps another bug?


btw: The out put from
printf "${file}" | sed --regexp-extended 's/(.)/\\\1/g'
alone is correct in dash:
\.\/\d\a\t\a\/\i\m\a\g\e\.\o\g\a

It's the command-substitution,.. which makes strange transformations.


Cheers,
Chris.

#538100#20
Date:
2011-08-21 05:48:36 UTC
From:
To:
retitle 538100 dash built-in echo expands \nnn sequences
severity 538100 wishlist
tags 538100 = upstream wontfix
merge 550399 538100
quit

Hi Christoph,

Christoph Anton Mitterer wrote:
[...]

Using

  printf '%s\n' "$file_entry_quoted"

works.

Sorry for the long silence,
Jonathan