Sourcing a file ending in \newline disables aliases for 1 command
Bash Version: 4.2 Patch Level: 37 Release Status: release Description: If a file with a command that ends in \newline is sourced, the next command issued in the command line does not interpret aliases but subsequent ones do. It's a minor issue easy to work around, but since it's surprising behaviour and some aliases are important, I thought I'd report it. In the real case where I used it, the command was 'rm' which was an alias to 'rm -i' to ask for confirmation, and it didn't ask. Repeat-By: $ alias hi=echo\ hello $ echo /bin/true\\ testbug.sh $ hi hello $ source testbug.sh $ hi bash: hi: command not found $ hi hello
Sourcing a file ending in \newline disables aliases for 1 command
Bash Version: 4.2 Patch Level: 37 Release Status: release Description: If a file with a command that ends in \newline is sourced, the next command issued in the command line does not interpret aliases but subsequent ones do. It's a minor issue easy to work around, but since it's surprising behaviour and some aliases are important, I thought I'd report it. In the real case where I used it, the command was 'rm' which was an alias to 'rm -i' to ask for confirmation, and it didn't ask. Repeat-By: $ alias hi=echo\ hello $ echo /bin/true\\ testbug.sh $ hi hello $ source testbug.sh $ hi bash: hi: command not found $ hi hello
Re: Sourcing a file ending in \newline disables aliases for 1 command
On Thu, Apr 2, 2015 at 4:40 PM, Pedro Gimeno pgwr-...@personal.formauri.es wrote: Bash Version: 4.2 Patch Level: 37 Release Status: release Description: If a file with a command that ends in \newline is sourced, the next command issued in the command line does not interpret aliases but subsequent ones do. It's a minor issue easy to work around, but since it's surprising behaviour and some aliases are important, I thought I'd report it. In the real case where I used it, the command was 'rm' which was an alias to 'rm -i' to ask for confirmation, and it didn't ask. Repeat-By: $ alias hi=echo\ hello $ echo /bin/true\\ testbug.sh $ hi hello $ source testbug.sh $ hi bash: hi: command not found $ hi hello Interesting. does the same on my system, but notice something in the following cut'n'paste [tsh009@it-johnmckown-linux junk]$ echo /bin/true\\ testbug.sh [tsh009@it-johnmckown-linux junk]$ od -tcx1 testbug.sh 000 / b i n / t r u e \ \n 2f 62 69 6e 2f 74 72 75 65 5c 0a 013 Note that testbug.sh does end in a LF, at least if I did it correctly. Also notice in the following transcript: [tsh009@it-johnmckown-linux junk]$ echo -n /bin/true |testbug.sh [tsh009@it-johnmckown-linux junk]$ od -tcx1 testbug.sh 000 / b i n / t r u e 2f 62 69 6e 2f 74 72 75 65 011 [tsh009@it-johnmckown-linux junk]$ source testbug.sh [tsh009@it-johnmckown-linux junk]$ hi hello [tsh009@it-johnmckown-linux junk]$ In this case, testbug.sh truly does NOT have an LF at the end, and there is no problem. Also notice, all by itself, not preceded by the source command: [tsh009@it-johnmckown-linux junk]$ \hi bash: hi: command not found... [tsh009@it-johnmckown-linux junk]$ Also notice: [tsh009@it-johnmckown-linux junk]$ hi bash: hi: command not found... Which is expected since enclosing the command in .. is quoted, which disables expanding aliases Since testbug.sh terminates with a \, it appears that the BASH shell is seeing your second command as \hi. Which _appears to me_ is what BASH would call a quoted value. And it is documented that aliases are not expanded when quoted. -- If you sent twitter messages while exploring, are you on a textpedition? He's about as useful as a wax frying pan. 10 to the 12th power microphones = 1 Megaphone Maranatha! John McKown
Re: Sourcing a file ending in \newline disables aliases for 1 command
I'm replying to this report, because it's the latest. This seems to be caused by last_read_token having an incorrect value set. `alias_expand_token' in parse.y relies on `command_token_position (last_read_token)' (and parser_state), to determine if an alias expansion should be performed. The correct value of last_read_token there should be of 10: alias_expand_token: last_read_token = 10 But, for some reason (I don't know if it's parse_and_execute or parse_command), after calling `evalstring', this value isn't restored to the correct one (shouldn't we care about toplevel's parser status?). Anyways, I wasn't able to produce a patch for this, because I don't know where last_read_token should be reset, or if there's some magic unwind_protect code to restore the tokens to the value before calling source/eval, but I hope this information makes it easier for Chet to produce a patch. Also, while looking at this, I found this: dualbus@yaqui ~ % bash -c 'eval \\; echo y' y dualbus@yaqui ~ % bash -ic 'eval \\; echo y' exit So, that eval is triggering a yacc_EOF, so that triggers the `exit' in the interactive shell. -- Eduardo Bustamante https://dualbus.me/
Re: Sourcing a file ending in \newline disables aliases for 1 command
John McKown wrote, On 2015-04-03 14:19: Note that testbug.sh does end in a LF, at least if I did it correctly. I've noticed that actually the LF is not important, only the final backslash is: $ alias hi=echo\ hello Without final LF: $ echo -n true\\ testbug.sh $ . testbug.sh $ hi bash: hi: command not found $ hi hello With final LF (same case as initially submitted): $ echo true\\ testbug.sh $ . testbug.sh $ hi bash: hi: command not found $ hi hello But if there is one more LF it doesn't reproduce: $ echo true\\ testbug.sh $ echo testbug.sh $ . testbug.sh $ hi hello In the first case the file is malformed, so that's not a problem. I think the second case should act as if the last command was in a line by itself without a terminating newline, but that's not what happens. It can also be argued that in that case the file is malformed too. In my real use case, the last lines were a set of options to which I was constantly adding or removing, with a backslash at the end of each line. At one point I wasn't careful and didn't remove the backslash from the last line. As I said, the next thing I did was to delete a file, and that's how I noticed it didn't prompt me for confirmation. I can easily add a ; in one line alone at the end of the file and insert the options before it. That'd work around this. Since testbug.sh terminates with a \, it appears that the BASH shell is seeing your second command as \hi. Which _appears to me_ is what BASH would call a quoted value. And it is documented that aliases are not expanded when quoted. On the other hand, this works as expected: $ echo true\\ testbug.sh $ . testbug.sh $ hi bash: hi: command not found My point with this last example is that it's not quoting the double quotes as if they were prefixed with a backslash. This is what happens when that's the case: $ \hi So it's not as simple as it acts as if preceded by a backslash. Also, it doesn't reproduce if the aliased command is inside the sourced file: $ echo true\\ testbug.sh $ echo hi testbug.sh $ . testbug.sh bash: truehi: command not found (which is expected). $ echo true\\ testbug.sh $ echo testbug.sh $ echo hi testbug.sh $ . testbug.sh hello (which is expected too).
Regression with declare -i and arrays
Hello Chet, You introduced a regression: [dual...@ma.sdf.org /tmp/tmp.ps6HXrLSZX/devel-]$ ./bash -c 'typeset -i x; x=([0]=1+1); echo $x' 1+1 vs dualbus@yaqui ~ % bash -c 'typeset -i x; x=([0]=1+1); echo $x' 2 The regression was introduced here: 06c3a57511953d09ac9ea262bc18bfdbcff23fc4 The patch that causes it: diff --git a/builtins/declare.def b/builtins/declare.def index 69c4703..5ed83a0 100644 --- a/builtins/declare.def +++ b/builtins/declare.def @@ -506,13 +506,13 @@ declare_internal (list, local_var) if (flags_on att_assoc) { var = make_new_assoc_variable (name); - if (offset == 0 no_invisible_vars == 0) + if (var offset == 0 no_invisible_vars == 0) VSETATTR (var, att_invisible); } else if ((flags_on att_array) || making_array_special) { var = make_new_array_variable (name); - if (offset == 0 no_invisible_vars == 0) + if (var offset == 0 no_invisible_vars == 0) VSETATTR (var, att_invisible); } else @@ -522,9 +522,11 @@ declare_internal (list, local_var) else { var = mkglobal ? bind_global_variable (name, (char *)NULL, 0) : bind_variable (name, (char *)NULL, 0); - if (no_invisible_vars == 0) + if (var no_invisible_vars == 0) VSETATTR (var, att_invisible); } + if (var == 0) + NEXT_VARIABLE (); } /* Can't take an existing array variable and make it a nameref */ else if ((array_p (var) || assoc_p (var)) (flags_on att_nameref)) Thanks to Geir, because he split the commits into logical commits and I was able to find this faster with git bisect. I caught it by running: make tests -- Eduardo Bustamante https://dualbus.me/
Re: Regression with declare -i and arrays
Nevermind. The patch is wrong, but at least it shows where the problem is (if needs braces, around line 529) El abr 3, 2015 8:48 PM, Eduardo A. Bustamante López dual...@gmail.com escribió: Here's a patch: diff --git a/builtins/declare.def b/builtins/declare.def index 5ed83a0..f0f9a6d 100644 --- a/builtins/declare.def +++ b/builtins/declare.def @@ -280,7 +280,7 @@ declare_internal (list, local_var) return (sh_chkwrite (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS)); } -#define NEXT_VARIABLE() free (name); list = list-next; continue +#define NEXT_VARIABLE() do { free (name); list = list-next; continue; } while(0) /* There are arguments left, so we are making variables. */ while (list) /* declare [-aAfFirx] name [name ...] */ -- Eduardo Bustamante https://dualbus.me/
Re: Regression with declare -i and arrays
Here's a patch: diff --git a/builtins/declare.def b/builtins/declare.def index 5ed83a0..f0f9a6d 100644 --- a/builtins/declare.def +++ b/builtins/declare.def @@ -280,7 +280,7 @@ declare_internal (list, local_var) return (sh_chkwrite (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS)); } -#define NEXT_VARIABLE() free (name); list = list-next; continue +#define NEXT_VARIABLE() do { free (name); list = list-next; continue; } while(0) /* There are arguments left, so we are making variables. */ while (list) /* declare [-aAfFirx] name [name ...] */ -- Eduardo Bustamante https://dualbus.me/