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 (<[email protected]>)
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 [email protected] http://tiswww.cwru.edu/~chet/
>