Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Is there a way to print or tee one thing to the console and still pass something else through to the next pipe? Something like:

echo dog | printOrWhatnot "PUTTING MY THING DOWN" | sed 's/dog/cat/g' | printOrWhatnot "FLIP IT"|rev

that would result in:

PUTTING MY THING DOWN
FLIP IT
tac

EDIT: This should also work with multiline input:

printOrWhatNot() {...}

seq 10 30 |printOrWhatNot searching for 3s | grep 3

would output

searching for 3s
13
23
30

Lars' answer seemed to only pass along the first input (here it would be 10)

Also ideally the output would come inline during processing which wasn't what I was seeing with Glen's answer. So

seq 10 30 |tee /dev/tty |printOrWhatNot searching for 3s | grep 3

would make for:

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
searching for 3s
13
23
30
share|improve this question
    
You're aware that all commands in a pipeline run concurrently, right? –  Stephane Chazelas Nov 5 '12 at 20:07
    
@Stephane Sure. Well maybe. The consequence here being that the message will be printed every time the function is called? –  Chris Nov 5 '12 at 20:27
    
No, just that you asking that the text be displayed after the output of tee and before the output of grep suggest that you may think they are run in sequence and not in parallel. –  Stephane Chazelas Nov 5 '12 at 21:02
add comment

2 Answers

up vote 2 down vote accepted

I'm not aware of any standard command for this purpose, but it's easy enough to craft one of your own in a little shell script. Create the following, make it executable, and add its location to your PATH.

Edit -- updated to handle multi-line standard input, and to handle spaces in the input.

printOrWhatnot:

 #!/bin/bash
 # printOrWhatnot script, to re-pipe stdin, while echoing something else via stderr

 # read stdin (possibly multi-lined) into $my_array[]:
 while read -t 1  piped
 do
    my_array=("${my_array[@]}" "$piped")
 done

 # echo the supplied arguments by sending them to stderr:
 echo "$@" 1>&2

 # now spew $my_array[], line by line, to any further processing:
 arrayLen=${#my_array[@]}
 for (( i=0; i<$arrayLen; i++ ));
 do
    echo ${my_array[$i]}
 done

Now it should work just as you suggested:

 myhost> echo dog | printOrWhatnot "PUTTING MY THING DOWN" | sed 's/dog/cat/g' | printOrWhatnot "FLIP IT"|rev
 PUTTING MY THING DOWN
 FLIP IT
 tac
share|improve this answer
    
Sorry for the comment spam. I think I found out my problem though. I've added another example in the question. –  Chris Nov 5 '12 at 19:37
    
Well, that does add a layer of complexity. It can still be accomplished with a shell script, by reading into an array -- updating answer. –  Lars Rohrbach Nov 5 '12 at 20:21
    
This is pretty much what I ended up going with. I got the same thing for handling spaces by wrapping the array in quotes when its being read. Thanks! –  Chris Nov 6 '12 at 20:34
add comment

You need to send your message to a different file descriptor than stdout, and just dump stdin to stdout untouched:

printOrWhatnot() { echo "$@" >&2; cat -; }

If you need your messages to (eventually) appear on stdout, change rev to rev 2>&1 or wrap your pipeline in braces:

{
    echo dog | 
    printOrWhatnot "PUTTING MY THING DOWN" | 
    sed 's/dog/cat/g' | 
    printOrWhatnot "FLIP IT" |
    rev
} 2>&1 
share|improve this answer
    
This method requires that your shell is a Bourne-shell variant (not csh or tcsh for instance), and that stdin isn't empty. But it is nicely compact. –  Lars Rohrbach Oct 31 '12 at 1:11
    
@LarsRohrbach, here "echo dog" is doing the job of producing data for stdin. –  glenn jackman Oct 31 '12 at 10:55
    
Well of course it is, in this case. I'm just speaking of usage of printOrWhatnot in general. –  Lars Rohrbach Oct 31 '12 at 14:36
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.