Re: Sourcing a file ending in \newline disables aliases for 1 command

2015-04-07 Thread Chet Ramey
On 4/3/15 3:55 PM, Eduardo A. Bustamante López wrote:

 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.

Thanks for the report.  This one was a trickier fix, since there are two
problems here.  The fix will be in the next release of bash and will show
up on the devel branch soon.

Chet
-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



Re: Sourcing a file ending in \newline disables aliases for 1 command

2015-04-06 Thread Chet Ramey
On 4/3/15 3:55 PM, Eduardo A. Bustamante López wrote:
 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:

No, it shouldn't, at least in normal use without setting it specially.
backslash-newline disappears; it's as if it was never read at all:

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_02_01

so last_read_token shouldn't change from WORD.

   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?).

We do, but source is defined to behave as if the lines are taken from the
current input source, so it modifies the parser state and that persists.

Maybe the thing to do is to just push a newline into last_read_token when
_evalfile returns, or call reset_parser().  I'll have to think about the
consequences of doing that and whether it will be noticeably backwards-
incompatible.

 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.

It does.

 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.

I didn't look closely at this yet, but it seems like the same class of fix
would work.

Thanks for your looking at this.

Chet
-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



Re: Sourcing a file ending in \newline disables aliases for 1 command

2015-04-03 Thread John McKown
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

2015-04-03 Thread Eduardo A . Bustamante López
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

2015-04-03 Thread Pedro Gimeno
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).