Harsh
Harsh

Reputation: 360

Using output of previous commands in bash

In Mathematica, it is possible to reuse the output of the previous command by using %.

Is something similar possible for bash (or some other shell)?

For example, I run a make which gives warnings, but I want to find all warnings. So, I type

make | grep "warning"

but I'm not able to see the output of the make then.

I would like to type something like this instead:

make
% | grep "warning"

Upvotes: 14

Views: 21390

Answers (5)

Ryan Hart
Ryan Hart

Reputation: 83

You could do this:

make
!! | grep "warning"

By using !! you tell it to repeat the last command in that spot, along with any other bash commands you want to add to it.

The downside is that if the command you are repeating takes a long time to execute, you'll have that much longer to wait unless you stored the output of the previous command to an output file first.

Upvotes: 4

juan
juan

Reputation: 31

Swap the stdout and stderr streams to log the entire stderr stream:

make 3>&2 2>&1 1>&3 3>&- | tee /dev/stderr > stderr.log

Upvotes: 3

bashfu
bashfu

Reputation: 21

If you use tee to duplicate the output stream to /dev/stderr, there's no need for a temp file; plus, after that, you can filter the stdout stream with sed to create a make_warning.log file - all in one line of Unix shell pipes.

make 2>&1 | tee /dev/stderr | \
   sed -E -n 's/(.*[Ww][Aa][Rr][Nn][Ii][Nn][Gg].*)/\1/p' > make_warning.log

Upvotes: 2

xenoterracide
xenoterracide

Reputation: 16865

I'm not sure if the make command sends warnings to stderr but I suspect it does. try this

make 2&>1 |grep 'warning'

it will redirect stderr to stdout.

Should also note that you can't grep anything that's not going to stdout.

Upvotes: 2

Carl Smotricz
Carl Smotricz

Reputation: 67820

Since the amount of output is indeterminate, it doesn't make sense for bash to store it for you for re-display. But there's an alternate solution to your problem:

The tee command allows you to duplicate an output stream to a file. So if you're willing to use a file for temporary storage, you can do something like this:

make | tee output.txt
grep "warning" output.txt

This solution avoids running make twice, which could be (a) expensive and (b) inconsistent: the second make may be doing less work than the first because some targets were already made the first time around.

Note: I haven't tried this. You may need to fiddle with joining the error and output streams, or such.

Upvotes: 15

Related Questions