First of all, I'd like to thank you for your responses.

Okay, now I understand a little better what's going on with recursion.

In most cases, I can now see what's wrong, but there's one specific case
where I can't quite figure out what's wrong.

bash -ic $'alias x=:\nx(){ id;};x'  # This case crash.
bash -ic $'alias x=:;x(){ id;};x'  # This case do not crash.

I understand that the crash is caused by recursion, but I don't quite
understand why the expansion of '\n' works as expected (crashes), but it
doesn't with the semicolon.

Please, can you explain me that?

El mié, 18 jun 2025 a las 20:30, Chet Ramey (<chet.ra...@case.edu>)
escribió:

> On 6/18/25 11:38 AM, Alberto Millán wrote:
>
> > Bash Version: 5.2
> > Patch Level: 37
> > Release Status: release
> >
> > Description:
> >      When I define an alias and a function with the same name, I
> experience
> > abnormal behavior.
> >      It seems to be especially dangerous when using a colon.
>
> I think there is a misunderstanding about exactly when alias expansion
> happens in the parsing process.
>
> The current version of the man page says:
>
> "Aliases allow a string to be substituted for a word that is in a  posi-
>   tion  in  the input where it can be the first word of a simple command.
>   Aliases have names and corresponding values that are set and unset  us-
>   ing  the alias and unalias builtin commands (see SHELL BUILTIN COMMANDS
>   below).
>
>   If the shell reads an unquoted word in the right  position,  it  checks
>   the  word to see if it matches an alias name.  If it matches, the shell
>   replaces the word with the alias value, and reads that value as  if  it
>   had been read instead of the word.  The shell doesn't look at any char-
>   acters following the word before attempting alias substitution."
>
> So as part of the tokenizing process, the shell reads words (and operators,
> etc.), one at a time. If it reads a word, and it's in the position where
> it could be the first word in a simple command, it tries alias expansion.
>
> Given that, we can see what happens here.
>
> >      alias x='echo foo'
> >      x(){ :;}
> >
> >      # It return:
> >      # -bash: syntax error near unexpected token `('
>
> Because what you get in the input after alias expansion is basically
>
> echo foo(){ :;}
>
> which is a syntax error.
>
>
> >      alias x='echo foo;'
> >      x(){ :;}
> >
> >      # It return similar but diferent error:
> >      # -bash: syntax error near unexpected token `)'
>
> This time what you get is
>
> echo foo;(){ :;}
>
> Which is a valid simple command, followed by a left paren, which can
> introduce a subshell or arithmetic command, followed by a right paren,
> which is a syntax error.
>
>
> >      alias x=:
> >      x(){ :;} # Not error yet but...
> >
> >      x
> >      # It return:
> >      # Segmentation fault (core dumped)
>
> You have managed to define and execute an infinitely recursive function:
>
> : () { :; }
> :
>
>
> >
> >      And when you put a colon at the end of the alias, the function
> > definition executes the alias.
> >      ```bash
> >      alias x='id;:'
> >      x(){ :;}
> >
> >      # It return the execution of the alias:
>
> You have again managed to define a recursive function; this time, you
> just executed a simple command before you did so.
>
>
> >      bash -i -c $'alias x=:\n         x(){ :;};x' # This crash.
> >      bash    -c $'alias x=:\n         x(){ :;};x' # This do not crash.
> >      bash -i -c $'alias x=:\nfunction x(){ :;};x' # This do not crash.
> >      bash -i -c  'alias x=:; function x(){ :;};x' # This do not crash.
> >      bash -i -c  'alias x=:;          x(){ :;};x' # This do not crash.
>
> Given the above, you should be able to figure out what these are doing.
> Keep in mind that bash doesn't expand aliases by default in non-
> interactive shells.
>
> --
> ``The lyf so short, the craft so long to lerne.'' - Chaucer
>                  ``Ars longa, vita brevis'' - Hippocrates
> Chet Ramey, UTech, CWRU    c...@case.edu    http://tiswww.cwru.edu/~chet/
>

Reply via email to