help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: i dont see my code error there ...


From: Greg Wooledge
Subject: Re: i dont see my code error there ...
Date: Thu, 31 Mar 2022 16:24:06 -0400

On Thu, Mar 31, 2022 at 09:52:08PM +0200, Alex fxmbsw7 Ratchev wrote:
> On Thu, Mar 31, 2022 at 9:42 PM Greg Wooledge <greg@wooledge.org> wrote:
> > In fact, if the whole purpose of this exercise is to add the redirections
> > when you're using time, maybe what you really want is a magic alias.
> >
> > unicorn:~$ t_helper() { local TIMEFORMAT=%Rs cmd; read -r _ _ cmd <
> > <(history 1); time eval "$cmd" >/dev/null 2>&1; }
> > unicorn:~$ alias t='t_helper # '
> > unicorn:~$ t if sleep 1; then echo zzzz; fi
> > 1.002s
> >
> > You're a big alias fan, so that should be right up your alley.  It lets
> > you skip adding the quotes around the "argument" of t, because it's not
> > really an argument at that point.
> >
> > i .. completly dont understand .. the what
> what does history 1 there in a read
> 
> okay now i halfway understood
> and # is the alias'es name heh ?

Magic aliases.  I'm surprised you've not run into them before, as much
as you seem to love aliases.
<https://www.chiark.greenend.org.uk/~sgtatham/aliases.html> is where
I first saw them, so I'm using Simon's name for them.

My variant (adapted from <https://wooledge.org/~greg/sprunge-magic-alias>)
does its magic by turning the entire "argument" part of the user's input
(everything after the alias's name) into a comment.  That way, it's not
parsed at all.  The user can put anything they want.

The history command is used to retrieve the user's input from the history
buffer, so we can know what they typed.  In this case, we pass that along
to eval.

Let's simplify it slightly:

unicorn:~$ helper() { local cmd; read -r _ _ cmd < <(history 1); printf '%s\n' 
"$cmd"; }
unicorn:~$ alias x='helper # '
unicorn:~$ x this; is; madness
this; is; madness

Here, you can see how the history command is being used.  The user types

x this; is; madness

And because x is an alias, this gets turned into

helper # this; is; madness

The helper function is called with no arguments, and it uses 'history 1'
to figure out what the user actually typed.  The read command strips out
the first two words (helper and #), and what's left in the cmd variable
is everything else: "this; is; madness".  That gets sent to printf, to be
printed.  Or in the original magic alias + helper, it gets sent to eval,
to be parsed and executed, with time in front of it, and with redirections.

As you can see, magic alias break all expectations.  When you see

unicorn:~$ x this; is; madness

you may think you know what's happening.  You see three simple commands
joined by semicolons into one line.  You expect "x this" to be executed
first, and then "is", and then "madness".

But the alias changes that.  Its substitution is performed on the user's
command before the parser even has a chance to look at the next word.
The x is replaced by "helper #" and then the parsing is restarted.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]