Re: %q with truncating size loses safeness of %q
In my case I was using process substitution to generate a dynamic bashrc file as part of invoking an SDK environment. Naturally those lines which emit environment variable assignments use %q I had one build version tracking variable which was to be limited to 7 characters and set to a lowercase form of the username. The most concise but surprisingly unsafe form is. printf 'BUILD_VER_SUFFIX=%.7q\n' "${USER,,}" That's clearly not artificially contrived; (though the user has the ability to directly mess up their build environment anyway if they so wish). The answer is obviously "don't do that" but it that requires a special obscure knowledge which isn't documented. Can we have bash printf to also not do that? Or if it must break the security feature got which it exists can at least be documented? I think I've made myself clear so I went harp on about it anymore unless I find a more egregious opportunity for abuse. Sam On Fri, 17 Apr 2020, 23:38 Robert Elz, wrote: > Date:Fri, 17 Apr 2020 16:12:20 -0400 > From:Chet Ramey > Message-ID: <4bacf2f0-9802-67d3-f30b-80e37d058...@case.edu> > > | I would say this is a programmer error. The way precisions work with > | string arguments is that the argument is fetched or generated (this > | includes generating the quoted string for %q or the expanded string for > | %b) and then printf writes number of bytes (!) from that generated > string > | specified by the precision. > > This happens only because of the cheap way we (and I presume you) > implement things - in any rational scheme, it would take the precision > chars from the source string, and then quote them. > > But that's hard - instead we just use printf to do the work, %q quotes > the arg string, and then the 'q' is changed to a 's' in the format, and > we just call printf(3) to do the work (padding, justification, ...) > > The only excuse for this is pragmatics, no-one would deliberately set > out to design something quite that bogus. > > The end result is as Greg said, "Don't do that", if precisions are > needed with %q do something like > > printf 'echo %q%q\n' "$(printf %.2s "a'b")" ';ls' > > which produces > > echo a\'\;ls > > which I expect is the desired result. > > kre > >
Re: [bug] PROMPT_COMMAND is not executed as expected in some situations
On 4/16/20 10:11 AM, Chet Ramey wrote: > On 4/16/20 9:21 AM, Franklin, Jason wrote: >> On 4/15/20 5:35 PM, Chet Ramey wrote: >>> These all pretty much all fall into the category of the editor reprinting >>> the prompt before it returns. >> >> Hmmm... >> >> So, is there no way to have Bash handle the printing of the prompt after >> the return of the command and of the editor? > > Bash doesn't have control at that point. It's readline running a bindable > function. It's as if you hit ^L when the readline line buffer was empty: > readline reprints the prompt, but should it call back to bash somehow -- > through a hook function that doesn't currently exist -- to execute > PROMPT_COMMAND? > >> This would allow PROMPT_COMMAND to function as expected. It is >> surprising to see status indicators in my prompt NOT be updated when >> using . > > I don't think that most people expect PROMPT_COMMAND in that situation. >> I thought that this would be easy. Is it really not possible to fix? > > I'm saying it's not a bug at all, and doesn't need fixing. As a programmer, I can understand that this may be a tough fix. However, as a user, I must say that I expect PROMPT_COMMAND to be run whenever PS1 is printed to prompt me for a new command. The bash man page makes this clear. To quote: PROMPT_COMMAND If set, the value is executed as a command prior to issuing each primary prompt. My PROMPT_COMMAND does a lot of neat stuff. It works flawlessly too, but obviously not after using, for example, , because it doesn't get invoked then. This means that indicators about the most recent command are not updated when I open an editor to enter a command (or use histverify or show completions). A simple example where the prompt is not updated as expected (this one doesn't involve PROMPT_COMMAND, but shows why a full prompt update is desired): $ bash --norc $ PS1='[$?] '"$PS1" # now, exit status is in prompt, which is pretty useful # use to edit and enter command "false" and save and quit # the exit status should be [1], but is [0], so the indicator is wrong I hope this clarifies my point of view on this issue. It may be a tough ask, so I don't expect a ton of effort to fix this if others aren't complaining. In any case, thanks so much for all of your magnificent work on Bash. I've been using Bash for years, and I don't plan to stop! I wish I had the knowledge of Bash internals to just code up a patch. I tried, but it was to no avail. :( Thanks! -- Jason Franklin
Re: looking for consistent C-c trap behavior
On 4/17/20 3:59 PM, gentoo_eshoes--- via Bug reports for the GNU Bourne Again SHell wrote: > I've noticed that if I trap SIGINT in a bash script, the behavior when > encountering C-c depends on whether an external command (eg. 'sleep 100') or > a builtin command (like 'read -p') was encountered. It's only `read', and it happens when bash is executing in default mode. Here's what I wrote (off-list) earlier this month about it; it has come up several times before: = The idea is that trapping the signal doesn't interrupt the read, kind of like a read system call getting restarted if interrupted by a signal and reading from the terminal. Since the read doesn't get interrupted, you have to satisfy it by entering newline. If you didn't have the trap on INT it would interrupt the read. Bash has behaved this way in its default mode for just about forever. In posix mode, it interrupts the read system call. = The behavior of running the trap action and restarting the read if it returns is still there in default mode for backwards compatibility. -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/
Re: [PATCH] Exit status by no-argument `return' for function calls in trap handlers
On 4/16/20 1:21 PM, Koichi Murase wrote: > Bash Version: 5.0 > Patch Level: 11 > Release Status: release > > Summary: > > The behavior of no-argument `return' in trap handlers has been > changed from Bash 4.4 to follow the description of POSIX. Recently > this behavior caused problems in my Bash script. I am wondering > whether this change actually matches with the behavior meant by > POSIX because the change introduces unreasonable constraints in > writing shell functions. > > For the condition of this special treatment of `return', POSIX says > ``When return is executed in a trap action''. Here are two possible > interpretation: (A) `return's specified in the argument string of > `trap' builtin are affected, or (B) all the `return's in entire > runtime function-call tree in trap processing are affected. I guess > that POSIX wanted to provide a way to exit functions that received > signals without changing the value of `$?'. If that is the case, > the POSIX should have meant (A). However, the current Bash > implementation behaves as if it follows the interpretation (B). The POSIX wording seems straightforward and implies (B). The `action' is a string that is defined to behave as if it were the argument to `eval', so it can be an arbitrary command, which makes (A) unlikely. You could always ask the austin-group list for an interpretation, or send me something that I could forward to the list for you. > If all the `return's in the entire function-call tree are affected > in trap processing as in the interpretation (B), one cannot reliably > use no-argument `return' to return the last-command exit status. To > avoid the problem, one has to always write the exit status > explicitly as `return $?', and there is no use case for no-argument > `return' at all. That's an unreasonable statement, throwing out all uses of return without an argument because of how it behaves while running a trap. -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/
Re: looking for consistent C-c trap behavior
Apr 18, 2020, 22:03 by chet.ra...@case.edu: > On 4/17/20 3:59 PM, gentoo_eshoes--- via Bug reports for the GNU Bourne > Again SHell wrote: > >> I've noticed that if I trap SIGINT in a bash script, the behavior when >> encountering C-c depends on whether an external command (eg. 'sleep 100') or >> a builtin command (like 'read -p') was encountered. >> > > It's only `read', and it happens when bash is executing in default mode. > That's pretty cool that's only 'read', I wrongly assumed(without any prior testing) that that applies to any builtin. I still haven't tested, I trust you. > Here's what I wrote (off-list) earlier this month about it; it has come > up several times before: > > = > The idea is that trapping the signal doesn't interrupt the read, kind of > like a read system call getting restarted if interrupted by a signal and > reading from the terminal. Since the read doesn't get interrupted, you have > to satisfy it by entering newline. If you didn't have the trap on INT it > would interrupt the read. > > Bash has behaved this way in its default mode for just about forever. In > posix mode, it interrupts the read system call. > can confirm that indeed `bash --posix` does interrupt the 'read -p' on first C-c, however, the inside-trap seen exit code is 0, but if the trap doesn't `exit` itself, then the exit code after the 'read -p' is seen correctly as 130, ie. $ ./sigintread.bash Press C-c here...^Cinterrupted sees exit code '0' Normal exit sees ec=130 Would it be possible to somehow get 130 even inside the trap function? this would then be equivalent with interrupting 'sleep' for example: $ ./sigintread.bash ^Cinterrupted sees exit code '130' Normal exit sees ec=130 On another note, I naively tried to patch out the POSIX requirement, for my own/local_use puposes but had no effect: in this code + /* posix mode SIGINT during read -e. We only get here if SIGINT is trapped. */ + if (posixly_correct && this_shell_builtin == read_builtin && sig == 2) + { + last_command_exit_value = 128|SIGINT; + throw_to_top_level (); + } by removing "posixly_correct &&" from above. I've no idea why that would have no effect, a bit stumped.I've even tried with a prior 'make clean'. The only explanation is that some other code that happens only during `POSIXly correct` mode is affecting this somehow...
Re: looking for consistent C-c trap behavior
Apr 18, 2020, 23:41 by gentoo_esh...@tutanota.com: > > On another note, I naively tried to patch out the POSIX requirement, for my > own/local_use puposes but had no effect: > in this code > + /* posix mode SIGINT during read -e. We only get here if SIGINT is > trapped. */ > + if (posixly_correct && this_shell_builtin == read_builtin && sig == 2) > + { > + last_command_exit_value = 128|SIGINT; > + throw_to_top_level (); > + } > by removing "posixly_correct &&" from above. I've no idea why that would have > no effect, a bit stumped. > I've even tried with a prior 'make clean'. The only explanation is that some > other code that happens only during `POSIXly correct` mode is affecting this > somehow... > regarding the above, I stand corrected: it does indeed have effect but only on 'read -e' (just as the comment states), that bash_event_hook() function isn't entered for 'read -p' which to me was surprising, yet no doubt correct(I'm guessing). The code that allows 'read -p' to be interrupted when posixly_correct, must then be somewhere else, I shall keep lookin', yet I fear I might not find it :-"
Re: [PATCH] Exit status by no-argument `return' for function calls in trap handlers
2020-04-19 5:12 Chet Ramey : > The POSIX wording seems straightforward and implies (B). The `action' > is a string that is defined to behave as if it were the argument to > `eval', so it can be an arbitrary command, which makes (A) unlikely. > > You could always ask the austin-group list for an interpretation, or > send me something that I could forward to the list for you. Thank you for the suggestion. Is the mailing list you mentioned above? I have created an account in opengroup.org and subscribed to the mailing list. I will later write a question on wording of `return' special builtin in that list. > That's an unreasonable statement, throwing out all uses of return without > an argument because of how it behaves while running a trap. OK. I agree that for the shell functions that will not be used in trap handlers, no-argument `return' can be used without problems. Actually the situation in my script (ble.sh) is a little bit special. In my script, some parts of Bash features are emulated. I run `eval -- "$PROMPT_COMMAND"' in SIGWINCH handler where `PROMPT_COMMAND' is specified by users so is not under the control of the script but under the control of the user. Naively, with interpretation (B), I need to put restrictions on the commands that can be specified in `PROMPT_COMMAND', on which there are no restrictions in the original Bash. The use of no-argument `return' is common, and such restrictions are non-trivial for users. In fact, there are already existing Bash configurations, that use no-argument `return' in `PROMPT_COMMAND', which I would like to support with my script. One example is `bash-preexec' (https://github.com/rcaloras/bash-preexec) which aims to provide a feature like `preexec' and `precmd' hooks of zsh. `bash-preexec' uses no-argument `return'. The configuration provided by iTerm2 for shell--terminal integration also uses this `bash-preexec' framework. I would appreciate it if you could provide me some suggestion on other ways to work around the general problems caused by such user-provided `PROMPT_COMMAND'? 2020-04-17 2:21 Koichi Murase : > Also, I have checked the behavior of other shells. `zsh', `ash' > family (dash/ash, busybox sh) and `posh' does not implement the > special treatment of `return' in trap handlers. `ksh' family > (ksh93, mksh) and `yash' implements the interpretation (B). There > is no existing implementation of (A). But currently I still think > the intepretation (A) is reasonable. If there is rationale for the > interpretation (B), I would like to know it. Let me correct this paragraph. Actually `zsh', `dash' and `busybox' implement the behavior of the interpretation (A). After my previous email, I noticed that there was an oversight in testing the shells. With the attached script `0015-test4.sh', $ bash 0015-test4.sh In trap-argument: last command preceding the trap action In a function call: last command preceding the trap action $ bash-4.3 0015-test4.sh In trap-argument: last command in the trap action In a function call: last command in the trap action $ zsh 0015-test4.sh In trap-argument: last command preceding the trap action In a function call: last command in the trap action $ dash 0015-test4.sh In trap-argument: last command preceding the trap action In a function call: last command in the trap action $ busybox sh 0015-test4.sh In trap-argument: last command preceding the trap action In a function call: last command in the trap action $ mksh 0015-test4.sh In trap-argument: last command preceding the trap action In a function call: last command preceding the trap action $ ksh 0015-test4.sh In trap-argument: last command preceding the trap action In a function call: last command preceding the trap action $ yash 0015-test4.sh In trap-argument: (failed to exit the function) In a function call: last command preceding the trap action $ posh 0015-test4.sh In trap-argument: last command in the trap action In a function call: last command in the trap action which can be summarized in the following list: Interpretation (A): zsh, dash, busybox Interpretation (B): bash-5.0, ksh, mksh Interpretation (B) [broken?]: yash Not implemented: bash-4.3, posh -- Koichi #!/bin/bash setexit() { return "$1"; } invoke() { kill -USR1 $$; return 222; } trap 'setexit 111; return' USR1 invoke case $? in (0) echo 'In trap-argument: last command preceding the trap action' ;; (111) echo 'In trap-argument: last command in the trap action' ;; (222) echo 'In trap-argument: (failed to exit the function)' ;; (*) echo 'In trap-argument: (unexpected)' ;; esac stat=99 handler() { setexit 111; return; } trap 'handler; stat=$?; return' USR1 invoke case $stat in (0) echo 'In a function call: last command preceding the trap action' ;; (111) echo 'In a function call: last command in the trap action' ;; (*) echo 'In a function call: (unexpected)' ;; esac