Display or redirect shell job control messages

TL DR

All job control messages / alarms are hidden when they occur inside the function. Iโ€™ll discuss it in more detail below, but @Barmar indicated that this problem can be reproduced by running the binary function failure code, for example:

crun() { /tmp/faulty $1 $2 $3 } 

I defined a function in my .zshrc to compile and run the source code using the following function:

 crun() { local file=$1 shift local exepath="$(mktemp)" if [[ $file =~ "\.c$" ]]; then gcc -g -Wall $file -o $exepath || return $? else echo "no filetype detected" return 126 fi $exepath " $@ " } 

What can be called in this way:

 % crun source.cc arg_1 arg_2 

This works for regular programs, but there is a problem that shell job control messages, such as those created from segfault, are not displayed.

As an example:

 % echo 'int main=0;' >> /tmp/faulty.c # a crashing c program % crun faulty.c % # no output generated 

While equivalent interactive commands will generate this:

 % g++ faulty.c -o /tmp/faulty && /tmp/faulty [1] 2894 segmentation fault (core dumped) # ๐Ÿข€ zsh job control output for SIGSEGV 

Is there a way to display these messages for a crash executable whose path is being dynamically computed? Ideally, without writing your own traps / signal handlers + exec , using sh -c "$exepath $@ " or completely creating a wrapper system(3) )

+5
source share
1 answer

You can get zsh to print a segmentation error message from a job if you run it as a background job and then immediately bring it to the forefront.

 "$exepath" " $@ " & fg 

This will cause zsh print messages for signals in the job running for $exepath .

The disadvantage is that you get a little more than you expected for:

 % crun faulty.c faulty.c:1:5: warning: 'main' is usually a function [-Wmain] int main=0; ^~~~ [2] 2080 [2] - running "$exepath" " $@ " zsh: segmentation fault (core dumped) "$exepath" " $@ " 

But as shown, you will get segfault messages printed in the terminal.

Since messages are printed by the interactive shell and not by the failure process, job messages are not redirected if you try to redirect stdout or stderr .

So, on the one hand, if you try to extract a useful result from your process and redirect it to another place, you do not need to worry about the fact that work messages are interfering. But it also means that you will not receive a segfault message if you try to redirect it with a stderr redirect.

Here's a demo of this effect, with line breaks, added between commands for clarity:

 % crun good.c > test [2] 2071 [2] - running "$exepath" " $@ " % cat test Hello, world! % crun faulty.c 2>test [2] 2092 [2] - running "$exepath" " $@ " zsh: segmentation fault (core dumped) "$exepath" " $@ " % cat test faulty.c:1:5: warning: 'main' is usually a function [-Wmain] int main=0; ^~~~ 

For more information, see the zsh job and signal documentation . You can also pull out the C file where the magic happens .

+1
source

Source: https://habr.com/ru/post/1269696/


All Articles