Link to home
Start Free TrialLog in
Avatar of bearware
bearwareFlag for United Kingdom of Great Britain and Northern Ireland

asked on

replicating stdout to stderr or stream 3

I am wondering if there is a command to make a copy of stdout to say stderr.
I need this so I can transform each one differently.

e.g.
I will call the command I an looking for replicate

(( echo "hello world" | replicate stdout,3 | sed -e "s/world/matt/g" ) 3>&1 1>&4 | sed -e "s/hello/brave new/g") 4>&1

I have found a solution for systems that have /dev/stderr and /dev/fd/3 etc
That is:
tee /dev/stderr
tee /dev/fd/3

I also found a solution in gawk, gawk supports the above discriptors internaly:
gawk  '{print $0; print $0 > "/dev/fd/3"}'

I am wondering if there is a standard command that can do it, where I dont need to write a program not even a tiny awk one.
Avatar of chris_calabrese
chris_calabrese

The standard way is with /dev/fd. If your system doesn't have /dev/fd, complain to the vendor.
man tee

example:
  command | tee -a file

if your shell support s file handles, file for tee can be a file handle, otherwise use named pipes
Avatar of bearware

ASKER

reply to ahoffmann:

If my a file handle you mean /dev/stderr /dev/fd/3 etc., then as noted in the question this only works on OSs that support it.

Using a shell that supports it makes no difference because it will not, and can not be expanded. The bash shell supports /dev/stderr for file redirection, e.g. >/dev/stderr >/dev/fd/3

If you have a different meaning please explain.
> if your shell support s file handles
I meant the shell (as written verbatim), not the underlaying OS or file system
/dev/fd/N is OS, but most shells have their own buil-in file descriptos (sh, bash, ksh, tcsh, etc. etc.)

I.g. it's a bad idea to rely on the OS devices like /dev/fd/3 (exception: /dev/null)
yes yes I dont want to rely on the underlying OS (because it cant do the job), So yes I am using only built ins of the shell.

Now ahoffmann says in his earlyer comment that I can do this with tee, A cant see how can you (ahoffmann) explain how this is done. I have no doubt that you know how, but can you explain to me.
does following not do what you want?

  command | tee -a existing-file
N     N   OOOO
NN  N    O     O
N  NN    O     O
N    N    OOOO  I would not say that it did not if it did. (repeating your answer does not make it work)

Do you remember the question?

I Am trying to get the data to a stream e.i. >&3 but also to another stream >&4. This requires duplicating the data. Tee does the duplication put insists on puting it in a file. This is OK if it is run on an OS where there are files that corespont to these streams.
nice shouting :-P

ok, you want filehandles and not files. Did you try with named pipes (see my first suggestion):
   mkfifo pipe3
   mkfifo pipe4
   exec 3< pipe3
   exec 4< pipe4
   command|tee -a pipe3 pipe4
# to be improved in many ways
I made a command as follows.: Done of the answers work as requested ( on a system that does not support special files (named pipes, speciel devices))

Thanks for trying to help.
 
#!/bin/bash
gawk -- '
{
   print $0;
   print $0 > "/dev/stderr";
}
'

ASKER CERTIFIED SOLUTION
Avatar of PAQ_Man
PAQ_Man
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial