Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Handling Double-quoted backslash
- X-seq: zsh-users 15076
- From: "Benjamin R. Haskell" <zsh@xxxxxxxxxx>
- To: Zsh Users <zsh-users@xxxxxxx>
- Subject: Re: Handling Double-quoted backslash
- Date: Sat, 22 May 2010 16:28:10 -0400 (EDT)
- In-reply-to: <AANLkTilsi-UtdCZJuv9hNNQs3XIQG_8MRilmXYQMfXaR@xxxxxxxxxxxxxx>
- List-help: <mailto:zsh-users-help@zsh.org>
- List-id: Zsh Users List <zsh-users.zsh.org>
- List-post: <mailto:zsh-users@zsh.org>
- Mailing-list: contact zsh-users-help@xxxxxxx; run by ezmlm
- References: <AANLkTineDxdmX6rYKFaq8MPMV-JM3skkSsJ69I7aNUfY@xxxxxxxxxxxxxx> <AANLkTilsi-UtdCZJuv9hNNQs3XIQG_8MRilmXYQMfXaR@xxxxxxxxxxxxxx>
On Fri, 21 May 2010, Bart Schaefer wrote:
> On Fri, May 21, 2010 at 8:58 PM, EG Galano <eg.galano@xxxxxxxxx> wrote:
> > I'm not certain if this is a bug because many different shells
> > handle the case differently. I started testing double-quoted
> > backslashes with the newline character to see how the different
> > shells handled the following commands. I'm no expert, but based on
> > what I've learned about escaping charcters, I would think TCSH is
> > the only one that handles it correctly. Is that not correct?
>
> What you've failed to account for is that shells also implement
> "echo" differently, so the output is not determined solely by the
> quoting.
Interestingly, the shells aren't consistent across the board regardless
of how they implement 'echo'. I don't think that makes one or the other
"correct", per se (If anything, tcsh is in the minority, empirically).
But I still thought it was worth sharing.
Printargs is just a stupid C program I whipped up to print out the
arguments character-by-character with some [\r\n\t] handling. (gcc -Wall
-o printargs{,.c})
zsh$ for l in bash zsh csh tcsh sh ksh fish psh dash mksh sash shish posh ; for s in 'a\nb' 'a\\nb' 'a\\\nb' ; printf "%s\t%s\t" $l $s && $l -c "printargs \"$s\"" 2>/dev/null
(The '2>/dev/null' kills a psh error under perl 5.12)
Results in the attached output. ('sh' is a symlink to 'bash', and 'csh'
is a symlink to 'tcsh')
So, with 1, 2, and 3 backslashes followed by an 'n':
bash, zsh, sh, ksh, fish, dash, mksh, sash, and posh keep 1, 1, and 2
backslashes
csh, tcsh, and shish keep 1, 2, and 3 backslashes
Only psh interprets the '\n' as a newline, and adds: 0, 1, or 2
preceding backslashes.
--
Best,
Ben
#include <stdio.h>
#include <ctype.h>
int main(int argc, char **argv) {
int i, j;
char c;
for (i = 1; i < argc; i++) {
if (i > 1) printf("\n");
printf("argv[%d]:", i);
for (j = 0; argv[i][j]; j++) {
c = argv[i][j];
printf(" ");
if (!isspace(c)) printf("%c", c);
else if (c == '\n') printf("(\\n)");
else if (c == '\r') printf("(\\r)");
else if (c == '\t') printf("(\\t)");
else printf("(%02x)",c);
}
printf("\n");
}
return 0;
}
bash a\nb argv[1]: a \ n b
bash a\\nb argv[1]: a \ n b
bash a\\\nb argv[1]: a \ \ n b
zsh a\nb argv[1]: a \ n b
zsh a\\nb argv[1]: a \ n b
zsh a\\\nb argv[1]: a \ \ n b
csh a\nb argv[1]: a \ n b
csh a\\nb argv[1]: a \ \ n b
csh a\\\nb argv[1]: a \ \ \ n b
tcsh a\nb argv[1]: a \ n b
tcsh a\\nb argv[1]: a \ \ n b
tcsh a\\\nb argv[1]: a \ \ \ n b
sh a\nb argv[1]: a \ n b
sh a\\nb argv[1]: a \ n b
sh a\\\nb argv[1]: a \ \ n b
ksh a\nb argv[1]: a \ n b
ksh a\\nb argv[1]: a \ n b
ksh a\\\nb argv[1]: a \ \ n b
fish a\nb argv[1]: a \ n b
fish a\\nb argv[1]: a \ n b
fish a\\\nb argv[1]: a \ \ n b
psh a\nb argv[1]: a (\n) b
psh a\\nb argv[1]: a \ (\n) b
psh a\\\nb argv[1]: a \ (\n) b
dash a\nb argv[1]: a \ n b
dash a\\nb argv[1]: a \ n b
dash a\\\nb argv[1]: a \ \ n b
mksh a\nb argv[1]: a \ n b
mksh a\\nb argv[1]: a \ n b
mksh a\\\nb argv[1]: a \ \ n b
sash a\nb argv[1]: a \ n b
sash a\\nb argv[1]: a \ n b
sash a\\\nb argv[1]: a \ \ n b
shish a\nb argv[1]: a \ n b
shish a\\nb argv[1]: a \ \ n b
shish a\\\nb argv[1]: a \ \ \ n b
posh a\nb argv[1]: a \ n b
posh a\\nb argv[1]: a \ n b
posh a\\\nb argv[1]: a \ \ n b
Messages sorted by:
Reverse Date,
Date,
Thread,
Author