printf builtin's %q format specifier -- Tilde not escaped?
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); }
Aborting prompt with Ctrl-c sets exit status variable ($?) to 130
Hi, please Cc: me as I'm not subscribed. When I abort a bash prompt using Ctrl-c, the $? variable is set to 130 just as if a job had been aborted. To illustrate, some terminal contents: jfs@knirps:~$ echo Hello Hello jfs@knirps:~$ echo $? 0 jfs@knirps:~$ echo H^C jfs@knirps:~$ echo $? 130 jfs@knirps:~$ My feeling is that aborting a prompt should not change the $? variable. >From the docs: ? Expands to the exit status of the most recently executed foreground pipeline. I don't think the prompt counts as a pipeline (it can't be job controlled). This behaviour is particularly annoying when I log out from an SSH session using Ctrl-c Ctrl-d: jfs@knirps:~$ ssh riese [...] jfs@riese:~$ foo^C jfs@riese:~$ logout Connection to riese closed. jfs@knirps:~$ echo $? 130 jfs@knirps:~$ What are your thoughts?
Re: Aborting prompt with Ctrl-c sets exit status variable ($?) to 130
On Wed, Jun 04, 2014 at 01:34:22PM -0600, Eric Blake wrote: > On 06/04/2014 01:28 PM, Dennis Williamson wrote: > >> My feeling is that aborting a prompt should not change the $? variable. > > I agree that it is annoying behavior that Ctrl-C changes $?, but at > least we're in good company, since ksh has the same behavior (well, > there $? is set to 258, since ksh takes advantage of the POSIX rule that > it can represent exit due to signal in $? by using values that are > unambiguous with regular exit). zsh almost has the same behavior, > except it sets $? to 1 instead of any indication that a signal occurred. Dash on the other hand doesn't change $?. I don't think we can speak of "exit" here.
Re: Aborting prompt with Ctrl-c sets exit status variable ($?) to 130
On Wed, Jun 04, 2014 at 05:40:10PM -0700, Ryan Cunningham wrote: > According to Dennis's e-mail, this is normal behavior, not a bug. Do not > attempt to fix it. That email only calculates 130 = 128 + SIGINT which I had already figured out. There was no argument that setting $? on prompt abort was not annoying (and unspecified) behaviour.