LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   shell script - copy stdout to file (https://www.linuxquestions.org/questions/programming-9/shell-script-copy-stdout-to-file-4175472007/)

kobigeu 08-03-2013 02:11 PM

shell script - copy stdout to file
 
hello,
I have 2 scripts. at the script1 I have this line
Code:

".....
./script2 >> $outputfile
.."

at script2 I print a lot and I need all to be at the stdout(because it will go out to $outputfile), and at some point at script2 I need to use all I have printed till now at script2.
cause I have at script2 line like this
Code:

"....
echo what I have printed till now at script2 | script3
..."

I tried something like that (the first line is at the beginnig of the script2, and the 2 last lines are at the end of script2, so it will go to $outputfile)
Code:

exec &> tmp5
....
cat tmp5 | script3
...
cat tmp5
rm tmp5

what's wrong with that(showed me empty lines at $outputfile)?
Is there a way where I can copy the stdout to tmp5(that it will be both on stdout and tmp5) - its the best solution for me.

ntubski 08-03-2013 05:56 PM

I think the problem is that you still have tmp5 open for writing when you cat it. Maybe try
Code:

# 3 = old stdout, 4 = old stderr, stdout and stderr to tmp5
exec 3>&1 4>&2 1>tmp5 2>&1
....
# close fds for tmp5, restore the original stdout and stderr
exec 1>&- 2>&- 1>&3- 2>&4-
<tmp5 script3
...
cat tmp5
rm tmp5

Possibly you can use tee if it's okay to run script3 in parallel, although since "...." will go in a subshell it might give you problems depending on what's in "...":
Code:

(....
) | tee >(script3)
...

Actually, would
Code:

(....
exec 1>&- 2>&-
...
) | tee >(script3)

avoid the subshell problems? There's even more concurrency, though.

kobigeu 08-04-2013 12:39 AM

Can you plz explain me what does the parameters(and &) mean?
Should I put this line together? exec 1>&- 2>&- 1>&3- 2>&4-<tmp5 script3
or it whould be 2 lines?
and what does it means <tmp5 script3
Thanks !

konsolebox 08-04-2013 07:48 AM

Quote:

Originally Posted by ntubski (Post 5002409)
since "...." will go in a subshell
Code:

(....
) | tee >(script3)


We could probably just use { } instead of ( ) for that. After all stdout returns back to original when code is no longer around { }.
Code:

{
    ...
} 2>&1 | tee >(script3)

Quote:

Originally Posted by ntubski (Post 5002409)
Code:

exec 1>&- 2>&-

This one causes bad file descriptor error. I think it's no longer necessary.
Code:

( exec >&-; echo -; ) > >(cat)
@kobigeu Try to read more about Redirection and Process Substitution in the bash manual.

ntubski 08-04-2013 08:52 AM

Quote:

Originally Posted by kobigeu (Post 5002498)
Can you plz explain me what does the parameters(and &) mean?

See Redirections, please ask specific questions if anything is unclear.

Quote:

Should I put this line together? exec 1>&- 2>&- 1>&3- 2>&4-<tmp5 script3
or it whould be 2 lines?
2 lines.

Quote:

and what does it means <tmp5 script3
It means the same as cat tmp5 | script3, it's more usual to write script3 <tmp5, but I wrote it like that to emphasize the similarity to the cat version.


Quote:

Originally Posted by konsolebox (Post 5002597)
We could probably just use { } instead of ( ) for that. After all stdout returns back to original when code is no longer around { }.

But it would still be in a subshell because it's part of a pipeline so it makes no difference, right?

Quote:

This one causes bad file descriptor error.
Hmm, I must have been thinking that the second part of the script doesn't have output, but that makes no sense, oops. :o

konsolebox 08-04-2013 09:05 AM

Quote:

Originally Posted by ntubski (Post 5002618)
But it would still be in a subshell because it's part of a pipeline so it makes no difference, right?[/CODE]

Since the context of it doesn't need to be placed on a subshell unlike those placed after pipe (|), it won't. This would still echo "Was in current shell.":
Code:

{ :; A="Was in current shell."; } > >(:); echo "$A"
Or
Code:

{ :; A="Was in current shell."; } | tee >(:); echo "$A"

ntubski 08-04-2013 09:15 AM

Quote:

Originally Posted by konsolebox (Post 5002623)
Since the context of it doesn't need to be placed on a subshell

I'm not sure if we are talking about the same "it"? The second example echoes nothing, which I think is what applies.

konsolebox 08-04-2013 09:43 AM

Now that's odd. With pipe you don't need to fork twice to create two processes on the background and share each other. Perhaps it's necessary to avoid errors or conflicts in other implementations of the shell.

Code:

I'm not sure if we are talking about the same "it"?
The part of the code or the context of the script that doesn't run in a subshell by default like those in { }.

Since we can't use pipes to maintain the code not running on a subshell we could just use process substitution twice:
Code:

{
    ...
} > >(exec tee >(script3)) 2>&1



All times are GMT -5. The time now is 01:54 PM.