After using `exec 1> file`, how can I stop the STDOUT redirection to a file and restore the normal operation of STDOUT?

I am new to shell scripts and I am using Ubuntu-11.10. In the terminal, after using the exec 1>file command, which commands I give to the terminal, its output is not displayed in the terminal. I know that STDOUT is redirected to a file, the output of these commands is redirected to a file.

My questions are here

  • As soon as I use exec 1>file , how can I get rid of this? That is, how can I stop the STDOUT redirection to a file and restore the normal operation of STDOUT (i.e. redirection to the terminal, not to the file)?

    I tried using exec 1>&- but it did not work, as this closes the STDOUT file descriptor.

  • Please shed light on this entire operation exec 1>file and exec 1>&-

  • What happens if we close the standard file descriptors 0, 1, 2 with exec 0>&- exec 1>&- exec 2>&- ?

+5
source share
4 answers

Q1

You need to prepare for recovery before you complete the initial exec :

 exec 3>&1 1>file 

To restore the original standard output later:

 exec 1>&3 3>&- 

The first exec copies the original file descriptor 1 (standard output) to file descriptor 3, then redirects standard output to the specified file. The second exec again copies the file descriptor 3 to standard output, and then closes the file descriptor.

Q2

It is a little open. It can be described at the C code level or at the command line level of the shell.

 exec 1>file 

just redirects the standard output (1) of the shell to the specified file. The file descriptor now refers to the named file; any output written to standard output will be transferred to a file. (Note that prompts in the interactive shell are written to standard error, not standard output.)

 exec 1>&- 

just closes the standard output of the shell. Now there is no open file for standard output. Programs can be frustrated if they run without standard output.

Q3

If you close all three standard inputs, standard output and standard error, the interactive shell will exit when standard input is closed (because it will receive EOF when it reads the next command). The shell script will continue to work, but the programs that it runs can be upset because they are guaranteed 3 open channels of files - standard input, standard output, standard error - and when your shell starts them, if there are no other / O input modules, they don’t receive the files they promised, and all hell can break (and the only way to find out that the exit status of the command is probably not zero).

+10
source

Q1 . There is an easy way to restore stdout to the terminal after being redirected to a file:

 exec >/dev/tty 

When storing the original file descriptor stdout usually requires that it be restored later, in this particular case, you want stdout be /dev/tty , so there is no need to do more.

 $ date Mon Aug 25 10:06:46 CEST 2014 $ exec > /tmp/foo $ date $ exec > /dev/tty $ date Mon Aug 25 10:07:24 CEST 2014 $ ls -l /tmp/foo -rw-r--r-- 1 jlliagre jlliagre 30 Aug 25 10:07 /tmp/foo $ cat /tmp/foo Mon Aug 25 10:07:05 CEST 2014 

Q2 : exec 1>file is a slightly more detailed way to make exec >file , which, as already mentioned, redirects stdout to this file if you have the right to create / write it. A file is created if it does not exist, it is truncated if it does.

exec 1>&- closes stdout, which is probably a bad idea in most situations.

Q3 : teams should be

 exec 0<&- exec 1>&- exec 2>&- 

Note the reverse redirection for stdin.

This can be simplified as follows:

 exec <&- >&- 2>&- 

This command closes all three standard file descriptors. This is a very bad idea. If you want the script to be disconnected from these channels, I would suggest this more robust approach:

 exec </dev/null >/dev/null 2>&1 

In this case, all output will be discarded instead of triggering an error, and all input will return only nothing instead of failure.

+4
source

So far, I completely agree with Jonathan Q1, some systems have /dev/stdout , so you can do exec 1>file; ...; exec 1>/dev/stdout exec 1>file; ...; exec 1>/dev/stdout

+1
source

The accepted answer is too much for me. So, I decided to summarize the answer to your original answer.

Using Bash version 4.3.39 (2) -release

On a x86 32-bit machine on a Cygwin machine

Given:

  • Stdin is fd # 0.
  • Stdout is fd # 1.
  • Stderr is fd # 2.

ANSWER (written in bash):

 exec 1> ./output.test.txt echo -e "First Line: Hello World!" printf "%s\n" "2nd Line: Hello Earth!" "3rd Line: Hello Solar System!" # This is uneccessary, but # it stops or closes stdout. # exec 1>&- # Send stdout back to stdin exec 1>&0 # Oops... I need to append some more data. # So, lets append to the file. exec 1>> ./output.test.txt echo -e "# Appended this line and the next line is empty.\n" # Send stdout back to stdin exec 1>&0 # Output the contents to stdout cat ./output.test.txt 

USEFUL-KEYWORDS:

Here are also presented here documents, here strings and process substitution for redirecting IO to Bourne, Bash, tcsh, zsh for Linux, BSD, AIX, HP, Busybox, Toybox, etc.

+1
source

Source: https://habr.com/ru/post/1201039/


All Articles