On 11/15/2010 12:08 PM, Stefan Berger wrote:
On 11/15/2010 01:50 PM, Eric Blake wrote:
> On 11/15/2010 11:24 AM, Stefan Berger wrote:
>> I tried this now and converted all \\ to \. I still get the same problem
>> here with dash using 'read -r line' now. The same problem exists with
>>
>> echo "\1"
>>
>> or
>>
>> echo '\1'
> Ah - the plot thickens, and the light bulb goes on for me. It's not
> just a problem with read, but also with your use of 'echo' to try and
> replay a just-read string. 'echo' and '\' don't mix. You have
to use
> printf for any chance of portability.
>
> printf %s\\n "\1"
> printf %s\\n '\1'
I am surprised that dash doesn't take the opportunity to already extend
"\1" or '\1' to char(1) in these cases. A mystery... :-)
As a shell argument in isolation, "\1" is undefined in POSIX, but
"\\1"
and '\1' are both the two-character strings for \ and 1.
Then, add printf or echo into the mix. echo is required to do further
interpolation of some \ sequences (although not all shells enforce this
by default), but not all sequences. For echo, dash does some
non-required interpolations that bash in xpg_echo mode does not do; but
for printf, both bash and dash provide non-required interpolations.
Printf is only required to do \ interpolation of its first argument, and
of any subsequent arguments that line up with %b in the first argument
(and what's worse, the interpolations required of the two positions of
printf arguments are different).
Therefore:
echo '\1' => undefined by POSIX (bash with xpg_echo outputs \1, bash in
normal mode outputs \1, dash outputs char(1))
echo '\\1' => defined by POSIX, but not portable (bash with xpg_echo
outputs \1, bash in normal mode outputs \\1, dash outputs \1)
echo "\1" => doubly undefined by POSIX
echo "\\1" => same problem as echo '\1'
echo '\01' => defined by POSIX, but not portable (bash with xpg_echo
outputs char(1), bash in normal mode outputs \01, dash outputs char(1))
printf %s\\n '\1' => well-defined as \1 everywhere
printf %s\\n "\1" => undefined by POSIX, although it tends to portably
output \1
printf %s\\n "\\1" => well-defined as \1 everywhere
printf '\1' => well-defined as char(1) everywhere
printf %b '\1' => undefined by POSIX, although it tends to portably
output char(1)
printf %b '\01' => well-defined as char(1) everywhere
printf %b "\1" => undefined by POSIX, although it tends to portably
output char(1)
--
Eric Blake eblake(a)redhat.com +1-801-349-2682
Libvirt virtualization library
http://libvirt.org