zsh-users
 help / color / mirror / code / Atom feed
* Accessing the evaluated expression which caused an error
@ 2021-09-03  1:42 Zach Riggle
  2021-09-03 17:14 ` Bart Schaefer
  0 siblings, 1 reply; 7+ messages in thread
From: Zach Riggle @ 2021-09-03  1:42 UTC (permalink / raw)
  To: Zsh Users

I have a neat script that registers a TRAPERR function, which dumps
out a backtrace, with the filename, line of source, and a few lines of
source around the line where the error was triggered.  Here's a
contrived example: https://i.imgur.com/jDOa8Pq.png

This is done using funcfiletrace, funcstack, and syntax-highlighted
with 'bat'.  I'm aware of funcsourcetrace, funcstack, and TRAPDEBUG /
ZSH_DEBUG_CMD as well, but none of these contain the actual expression
evaluated -- just the input to zsh.

These are excellent to show a backtrace, but I'm curious whether there
are additional functions that I might be able to leverage to show the
fully-evaluated expression which caused TRAPERR to be invoked.

I know that zsh has the data internally, since "zsh -x" shows the
fully-evaluated expression, so that data must be available somewhere,
even if it's not exposed in a shell variable.

I looked through the docs, as well as the output of "env" and
"declare" from within TRAPERR, but couldn't find anything helpful.

Thanks!
Zach Riggle


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Accessing the evaluated expression which caused an error
  2021-09-03  1:42 Accessing the evaluated expression which caused an error Zach Riggle
@ 2021-09-03 17:14 ` Bart Schaefer
  2021-09-03 17:38   ` Zach Riggle
  0 siblings, 1 reply; 7+ messages in thread
From: Bart Schaefer @ 2021-09-03 17:14 UTC (permalink / raw)
  To: Zach Riggle; +Cc: Zsh Users

On Thu, Sep 2, 2021 at 6:43 PM Zach Riggle <zachriggle@gmail.com> wrote:
>
> I'm aware of funcsourcetrace, funcstack, and TRAPDEBUG /
> ZSH_DEBUG_CMD as well, but none of these contain the actual expression
> evaluated -- just the input to zsh.
>
> I know that zsh has the data internally, since "zsh -x" shows the
> fully-evaluated expression, so that data must be available somewhere,
> even if it's not exposed in a shell variable.

Hm.  What xtrace does is dump each individual shell word ... it just
happens to dump them in the order that puts them together as an
"expression".  But you'll notice it's not actually an expression, it's
just e.g. a single simple command.  In fact it's even a bit weird for
some structured commands (look at the output for a "case" statement
for example).

It's correct that none of this is captured in any sort of format that
would be usable by a shell script.  It never exists all at once in
such a format internally.

What exactly might you want captured?


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Accessing the evaluated expression which caused an error
  2021-09-03 17:14 ` Bart Schaefer
@ 2021-09-03 17:38   ` Zach Riggle
  2021-09-04 20:08     ` Bart Schaefer
  0 siblings, 1 reply; 7+ messages in thread
From: Zach Riggle @ 2021-09-03 17:38 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Zsh Users

> What exactly might you want captured?

Very frequently I build a create an array that contains a command, e.g.

    declare -a cmd=( echo hello world )

And invoke it like:

    "${cmd[@]}"

When I xtrace, it will print out the values inside the array.

    +wat.sh:2> cmd=( echo hello world )
    +wat.sh:3> echo hello world

With TRAPDEBUG or TRAPERR, all I get is the "${cmd[@]}". None of the
Zsh-supplied arrays (funcfilesource etc.) contain that.  I originally
had some hope that $_ would work, but it appears not to.

Zach Riggle

On Fri, Sep 3, 2021 at 12:14 PM Bart Schaefer <schaefer@brasslantern.com> wrote:
>
> On Thu, Sep 2, 2021 at 6:43 PM Zach Riggle <zachriggle@gmail.com> wrote:
> >
> > I'm aware of funcsourcetrace, funcstack, and TRAPDEBUG /
> > ZSH_DEBUG_CMD as well, but none of these contain the actual expression
> > evaluated -- just the input to zsh.
> >
> > I know that zsh has the data internally, since "zsh -x" shows the
> > fully-evaluated expression, so that data must be available somewhere,
> > even if it's not exposed in a shell variable.
>
> Hm.  What xtrace does is dump each individual shell word ... it just
> happens to dump them in the order that puts them together as an
> "expression".  But you'll notice it's not actually an expression, it's
> just e.g. a single simple command.  In fact it's even a bit weird for
> some structured commands (look at the output for a "case" statement
> for example).
>
> It's correct that none of this is captured in any sort of format that
> would be usable by a shell script.  It never exists all at once in
> such a format internally.
>
> What exactly might you want captured?


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Accessing the evaluated expression which caused an error
  2021-09-03 17:38   ` Zach Riggle
@ 2021-09-04 20:08     ` Bart Schaefer
  2021-09-05  0:26       ` Zach Riggle
  0 siblings, 1 reply; 7+ messages in thread
From: Bart Schaefer @ 2021-09-04 20:08 UTC (permalink / raw)
  To: Zach Riggle; +Cc: Zsh Users

On Fri, Sep 3, 2021 at 10:38 AM Zach Riggle <zachriggle@gmail.com> wrote:
>
> > What exactly might you want captured?
>
> Very frequently I build a create an array that contains a command [...]
> And invoke it like:
>
>     "${cmd[@]}"

Given that you're doing it that way (rather than say "eval" it), you
should be able to use TRAPDEBUG and just do this:

TRAPDEBUG() { ACTUAL_CMD=${(e)ZSH_DEBUG_CMD} }

You may want some other "protection" around that, such as only doing
it when ZSH_DEBUG_CMD matches a pattern.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Accessing the evaluated expression which caused an error
  2021-09-04 20:08     ` Bart Schaefer
@ 2021-09-05  0:26       ` Zach Riggle
  2021-09-05  1:44         ` Lawrence Velázquez
  2021-09-05  2:08         ` Bart Schaefer
  0 siblings, 2 replies; 7+ messages in thread
From: Zach Riggle @ 2021-09-05  0:26 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Zsh Users

[-- Attachment #1: Type: text/plain, Size: 754 bytes --]

Will the (e) actually evaluate the parameters and execute them again? Or
just a single layer of expansion?

On Sat, Sep 4, 2021 at 3:08 PM Bart Schaefer <schaefer@brasslantern.com>
wrote:

> On Fri, Sep 3, 2021 at 10:38 AM Zach Riggle <zachriggle@gmail.com> wrote:
> >
> > > What exactly might you want captured?
> >
> > Very frequently I build a create an array that contains a command [...]
> > And invoke it like:
> >
> >     "${cmd[@]}"
>
> Given that you're doing it that way (rather than say "eval" it), you
> should be able to use TRAPDEBUG and just do this:
>
> TRAPDEBUG() { ACTUAL_CMD=${(e)ZSH_DEBUG_CMD} }
>
> You may want some other "protection" around that, such as only doing
> it when ZSH_DEBUG_CMD matches a pattern.
>
-- 

*Zach Riggle*

[-- Attachment #2: Type: text/html, Size: 1368 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Accessing the evaluated expression which caused an error
  2021-09-05  0:26       ` Zach Riggle
@ 2021-09-05  1:44         ` Lawrence Velázquez
  2021-09-05  2:08         ` Bart Schaefer
  1 sibling, 0 replies; 7+ messages in thread
From: Lawrence Velázquez @ 2021-09-05  1:44 UTC (permalink / raw)
  To: Zach Riggle, Bart Schaefer; +Cc: zsh-users

On Sat, Sep 4, 2021, at 8:26 PM, Zach Riggle wrote:
> Will the (e) actually evaluate the parameters and execute them again? 
> Or just a single layer of expansion?

https://zsh.sourceforge.io/Doc/Release/Expansion.html#Parameter-Expansion-Flags

  e
    Perform single word shell expansions, namely parameter expansion,
    command substitution and arithmetic expansion, on the result.
    Such expansions can be nested but too deep recursion may have
    unpredictable effects.

-- 
vq


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Accessing the evaluated expression which caused an error
  2021-09-05  0:26       ` Zach Riggle
  2021-09-05  1:44         ` Lawrence Velázquez
@ 2021-09-05  2:08         ` Bart Schaefer
  1 sibling, 0 replies; 7+ messages in thread
From: Bart Schaefer @ 2021-09-05  2:08 UTC (permalink / raw)
  To: Zach Riggle; +Cc: Zsh Users

On Sat, Sep 4, 2021 at 5:27 PM Zach Riggle <zachriggle@gmail.com> wrote:
>
> Will the (e) actually evaluate the parameters and execute them again? Or just a single layer of expansion?

Well ... it only does a single layer, but the string value of
ZSH_DEBUG_CMD is not itself specially quoted, so you only want to
apply (e) to cases like "${cmd[@]}" where you've deliberately added an
extra layer of quoting and want to peek inside it.

Then of course you probably want to put the quoting back again ... I
guess it ends up something like:

TRAPDEBUG() {
  if function {
    setopt localoptions extendedglob
    [[ $ZSH_DEBUG_CMD = \"[^\"](#c1,)\" ]]
  }
  then ZSH_DEBUG_CMD=${(@q-)${(z)${(e)${(Q)ZSH_DEBUG_CMD}}}}
  fi
  print -r -- $ZSH_DEBUG_CMD
}


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2021-09-05  2:09 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-03  1:42 Accessing the evaluated expression which caused an error Zach Riggle
2021-09-03 17:14 ` Bart Schaefer
2021-09-03 17:38   ` Zach Riggle
2021-09-04 20:08     ` Bart Schaefer
2021-09-05  0:26       ` Zach Riggle
2021-09-05  1:44         ` Lawrence Velázquez
2021-09-05  2:08         ` Bart Schaefer

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).