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); }