[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
printf builtin's %q format specifier -- Tilde not escaped?
From: |
Jens Stimpfle |
Subject: |
printf builtin's %q format specifier -- Tilde not escaped? |
Date: |
Tue, 7 Aug 2012 15:37:18 +0200 |
User-agent: |
Mutt/1.5.20 (2009-06-14) |
Bash's printf builtin has a %q format specifier, which, according to the
documentation, "causes printf to output the corresponding argument in a
format that can be reused as shell input".
My intuitive interpretation of "can be reused as shell input" could be
approximated by "can be used as a substring of a shellscript so that it
is parsed as a single argument to a command, equal to the input
argument".
In other words, %q should be the inverse operation to shell parsing, in
the sense that, for a concrete example,
eval "echo $(printf %q ANY)"
should be equal to
echo ANY
where ANY is an arbitrary sequence of characters, with the constraint
that it must parse to a single word.
What seems wrong to me is that the tilde character (~) is not escaped
$ eval "echo $(printf %q '~')"
/home/jens
$ echo '~'
~
In the bash source, tilde-escaping code already exists, but it is
commented out. How about turning this back on? Or am I just
misunderstanding what %q should do?
Have a nice day
-Jens Stimpfle
----- From lib/sh/shquote.c ------
char *
sh_backslash_quote (string)
char *string;
{
int c;
char *result, *r, *s;
result = (char *)xmalloc (2 * strlen (string) + 1);
for (r = result, s = string; s && (c = *s); s++)
{
switch (c)
{
case ' ': case '\t': case '\n': /* IFS white space */
case '\'': case '"': case '\\': /* quoting chars */
case '|': case '&': case ';': /* shell metacharacters
*/
case '(': case ')': case '<': case '>':
case '!': case '{': case '}': /* reserved words */
case '*': case '[': case '?': case ']': /* globbing chars */
case '^':
case '$': case '`': /* expansion chars */
case ',': /* brace expansion */
*r++ = '\\';
*r++ = c;
break;
#if 0
case '~': /* tilde expansion */
if (s == string || s[-1] == '=' || s[-1] == ':')
*r++ = '\\';
*r++ = c;
break;
case CTLESC: case CTLNUL: /* internal quoting
characters */
*r++ = CTLESC; /* could be '\\'? */
*r++ = c;
break;
#endif
case '#': /* comment char */
if (s == string)
*r++ = '\\';
/* FALLTHROUGH */
default:
*r++ = c;
break;
}
}
*r = '\0';
return (result);
}
- printf builtin's %q format specifier -- Tilde not escaped?,
Jens Stimpfle <=