Is there a way to run a command as the last item just before rex exits

26 views
Skip to first unread message

David Woodyard

unread,
May 4, 2020, 2:25:05 AM5/4/20
to Rex Users
Since the output from several computers will be intermixed on the screen,
I would like to print a status line (of my own creation) for each computer just before rex exits.

Is that possible?

Thanks,

David

erkif...@gmail.com

unread,
May 23, 2020, 9:30:02 AM5/23/20
to rex-...@googlegroups.com
Hi David,
yes, perhaps the most "rex-ish" way is to collect the results of a task
at the end of the task code into a shared variable, and use an
`after_task_finished` [1] hook to display the results.

Something like this:

```perl
use strict;
use warnings;

use Rex -feature => [ '1.4', 'exec_autodie' ];
use Data::Printer;

BEGIN {
use Rex::Shared::Var;
share qw(%results_for);
}

task 'status_line', sub {
say 'doing stuff';

# collecting results
my $hostname = run 'hostname';
my $result = run 'whoami';

$results_for{$hostname} = $result;
};

after_task_finished 'status_line' => sub {
say 'Collected results:';
p %results_for;
};
```
I've copied the same code into a gist[2] as well.

[1]: https://metacpan.org/pod/Rex::Commands#after_task_finished
[2]: https://gist.github.com/ferki/dfe59dda22710c719c17697ccb193051

Hope this helps,
FErki

David Woodyard

unread,
May 29, 2020, 9:58:33 PM5/29/20
to Rex Users
Thanks for your help,

This worked as I needed. Three items, however:

1) The output from the line 'p %results_for;' is in color even though I used
the -m on the command line. Yellow on white background is very hard to read.
Redirecting to a file does not capture the output from the 'p %results_for;'
line.
Are there any options to print the results using a different method or make output monochrome or another color?
 
2) I use $TASK = $ARGV[0] to get the task I am running. Then changed the line:
after_task_finished 'status_line' => sub {
to
after_task_finished "$TASK" => sub {
And that worked.
Any issues with using a variable for the task name that would cause a problem?

3) I assume that the 'after_task_finished' code can be placed anywhere,
correct?

Thanks again,

David

erkif...@gmail.com

unread,
May 30, 2020, 2:30:02 AM5/30/20
to rex-...@googlegroups.com
Hi David,

On 2020-05-29 18:58, David Woodyard wrote:
>This worked as I needed. Three items, however:

thanks for the feedback, I'm glad it worked for you.

>
>1) The output from the line 'p %results_for;' is in color even though I used
>the -m on the command line. Yellow on white background is very hard to read.

That is because the function `p` (which prints the content of the data
structure) belongs to Data::Printer, and not to Rex. Please see its own
documentation on how to customize its output, including colorization:
https://metacpan.org/pod/Data::Printer

Alternatively, it might also be possible to strip terminal color codes
in a shell pipeline: `rex my_task | strip color codes here`, but that
sounds less ideal.

>Redirecting to a file does not capture the output from the 'p %results_for;'
>line.

Again, that's because Data::Printer prints to STDERR by default
(https://metacpan.org/pod/Data::Printer#Changing-output-targets). You
can either configure it to print somewhere else, or you can redirect
both STDERR and STDOUT of Rex output to your file.

>Are there any options to print the results using a different method or make
>output monochrome or another color?

I simply used Data::Printer in my examples simply because I prefer that,
but please note that Rex code is just Perl code. Therefore apart from
configuring Data::Printer according to your exact needs, of course you
may use any other perl function or module to print the contents.

>
>2) I use $TASK = $ARGV[0] to get the task I am running. Then changed the
>line:
>after_task_finished 'status_line' => sub {
>to
>after_task_finished "$TASK" => sub {
>And that worked.
>Any issues with using a variable for the task name that would cause a
>problem?

That's an interesting take I haven't seen before, and I think it's a
good example of Rex's versatility. I believe the original intent here is
"please execute this hook after any task".

For that, the documentation of `after_task_finished` I linked earlier
(https://metacpan.org/pod/Rex::Commands#after_task_finished) mentions,
that the special task name 'ALL' can be used to run code after all tasks
(or the task name can be a regular expression matching the tasks where
you need to attach the hook). I think I would use that, instead of
dynamically attaching the hook to whatever I run currently.

Either way, Rex is friendly, so trusts you to be the one who knows what
approach fits your use case best. So as long as it works for you, that's
your solution :)

>
>3) I assume that the 'after_task_finished' code can be placed anywhere,
>correct?

The `after_task_finished` docs
(https://metacpan.org/pod/Rex::Commands#after_task_finished) say that
"Please note, this must come after the definition of the specified
task."

Hope this helps, and should you need further support, please consider
joining the community discussion via IRC (Freenode #rex, or
https://kiwiirc.com/nextclient/#irc://irc.freenode.net/#rex?nick=mc-guest-?).

Cheers,
FErki

David Woodyard

unread,
Jun 1, 2020, 11:49:36 AM6/1/20
to Rex Users


On Monday, May 4, 2020 at 1:25:05 AM UTC-5, David Woodyard wrote:
If I need to post this as a new thread let me know.

Using:

use Rex -feature => [ '1.4', 'exec_autodie' ];

I have seen rex exit before the task was finished.
If I comment out the above line the task completes correctly.

The exit occurs after the following command is run and $RUN = 0 on return.
$RUN = run "grep -Fch -- \"$ADDLINE\" $FNAME";

If you need additional info let me know.

Your thoughts,
David


erkif...@gmail.com

unread,
Jun 1, 2020, 12:20:02 PM6/1/20
to rex-...@googlegroups.com
Hi David,

On 2020-06-01 08:49, David Woodyard wrote:
>Using:
>
>use Rex -feature => [ '1.4', 'exec_autodie' ];
>
>I have seen rex exit before the task was finished.

Yes, this is the exact purpose of `exec_autodie` feature flag. It tells
rex to die immediately as soon as there's any execution errors detected.

>If I comment out the above line the task completes correctly.
>
>The exit occurs after the following command is run and $RUN = 0 on return.
>$RUN = run "grep -Fch -- \"$ADDLINE\" $FNAME";

Then it means that command (`grep -Fch -- \"$ADDLINE\" $FNAME`) returns
an exit code that indicates failure (e.g. `grep` didn't match anything).

Without `exec_autodie` it could probably continue here, but that would
also hide other errors from you that you might definitely want to know
about. In some situations, it might be even dangerous to continue after
an unhandled error, so it's best to keep the feature flag enabled, and
to add some error handling to the task.

>If you need additional info let me know.

It seems like a completely different question. Let's avoid mixing things
within a thread, please.

If you need further help, please ask us on IRC.

Cheers,
FErki
Reply all
Reply to author
Forward
0 new messages