Ulisses Alonso <[EMAIL PROTECTED]> writes: > Hi all > > I would like to know _how to copy_ (not start a new shell, eg: script) > stdout and stderr _from a shell script_ to a file. Also It is interesting > for me if there is a way to stop copying stdout and stderr... > > Thanks in advance, > > > Ulisses
Well, I'm not entirely certain what you mean, so I'll just say several things that might answer your question and hope that one of them tells you what you want to know. Suppose I have a simple shell script: #!/bin/sh echo "Guvf vf n frperg zrffntr." | tr a-zA-Z n-za-mN-ZA-M And I call this script foo. I make it executable so that I can call it like this: cush:~$ ./foo This is a secret message. Now, I decide I want to redirect this into a file. I do: cush:~$ ./foo > sekritfile Ok. So I can redirect all of foo's stdout into a file. But suppose I made a mistake in foo (say, I added an extra argument to the `tr' command). Then I get: cush:~$ ./foo > sekritfile tr: too many arguments Try `tr --help' for more information. Well, I want to redirect both foo's stdout and stderr into a file. Ok; I do this by saying "redirect stdout to sekritfile and redirect stderr to the same place as stdout": cush:~$ ./foo > sekritfile 2>&1 All well and good. I can even do fancy things like redirecting stdout and stderr to two different files: cush:~$ ./foo > sekritfile 2> errfile Ok. So far so good. Now suppose I don't want to have to specify where the stuff in foo goes on the commandline; suppose I want the shell script to just redirect everything all the time. I can do this by using the shell builtin command 'exec' in a slightly unusual way: #!/bin/sh exec > sekritfile 2> errfile echo "Guvf vf n frperg zrffntr." | tr a-zA-Z n-za-mN-ZA-M So now what happens is that when I do: cush:~$ ./foo Is that the output of the tr command is redicted to 'sekritfile' and the stderr of the tr command (and any following commands) is redirected to 'errfile'. I could redirect them both to the same place using: exec > sekritfile 2>&1 So far so good. But what if I want to redirect something and then undo the redirection? Say, if I had: #!/bin/sh echo "Guvf vf n frperg zrffntr." | tr a-zA-Z n-za-mN-ZA-M echo "Done decoding." And I wanted the first line redirected, and the second not. Then, I just need to save the original destinations of stdout and stderr, like this: #!/bin/sh exec 3>&1 4>&2 > sekritfile 2>&1 echo "Guvf vf n frperg zrffntr." | tr a-zA-Z n-za-mN-ZA-M exec >&3 2>&4 echo "Done decoding." Then, only the first echo command gets redirected to a file. cush:~$ ./foo Done decoding cush:~$ cat sekritfile This is a secret message. But notice: cush:~$ ./foo > msgfile cush:~$ cat msgfile Done decoding. cush:~$ cat sekritfile This is a secret message. Now, suppose that instead of redirecting output, I want to copy it. (That is, I still want to see the output on the screen). This means the output has to go to two places - the file and the screen. There are a few ways to do this - I'm only going to show one involving the 'tail' command. The problem is that the shell won't split output by itself, and won't do overall redirections (like the exec commands above) into pipes. However, we can do this: #!/bin/sh cat /dev/null > sekritfile # create it so that tail doesn't complain tail -f sekritfile & tailpid=$! exec >> sekritfile exec 2>&1 ... ... more commands here ... sleep 2 kill -1 $tailpid This causes the shell to dump stdout and stderr into the file sekritfile and at the same time starts up a process (the tail -f) that reads the file and displays its contents. The last kill command is necessary to stop the 'tail' process when the script is done. If you want to do this and only want to redirect portions of the script, you can do: #!/bin/sh cat /dev/null > sekritfile tail -f sekritfile & tailpid=$! exec 3>&1 4>&2 exec >> sekritfile exec 2>&1 ... ... these commands get saved to the file ... exec 5>&1 6>&2 1>&3 2>&4 ... ... these commands don't go to the file ... exec 1>&5 2>&6 ... ... these commands go to the file ... sleep 2 kill -1 $tailpid I hope this answers your question. -- Unsubscribe? mail -s unsubscribe [EMAIL PROTECTED] < /dev/null