Something that you can also do, although to my consideration it is something "extreme". It is redirecting all terminal errors to a file.
The terminal is a program, and like every program it has file descriptors to communicate with others.
You can see the file descriptors that this process has in its information folder in /proc/<pid>/fd
To know the pid of your terminal you can do this $ echo $$
and it will display the pid of your terminal in progress, let's say something similar happens.
$ echo $$
13
Then "13" is the pid of your terminal. Now you execute this:
$ ls -la /proc/13/fd # recuerda que esto es sólo un ejemplo de pid.
total 0
dr-x------ 2 usuario usuario 0 Oct 10 23:38 .
dr-xr-xr-x 7 usuario usuario 0 Oct 10 23:38 ..
lrwx------ 1 usuario usuario 0 Oct 11 23:12 0 -> /dev/tty3 #nota estos descriptores de archivo
lrwx------ 1 usuario usuario 0 Oct 11 23:10 1 -> /dev/tty3 #este
lrwx------ 1 usuario usuario 0 Oct 11 23:10 10 -> /dev/tty3
lr-x------ 1 usuario usuario 0 Oct 11 23:10 12 -> /usr/share/zsh/functions/Completion.zwc
lrwx------ 1 usuario usuario 0 Oct 11 23:10 2 -> /dev/tty3 # y este. Trabajaremos con este.
This program we ran to make a rollback later. While we have to keep the fact that the fd 2 is a symbolic link to /dev/tty3
Now I present you exec
. It is a built-in bash that replaces the terminal with the command that you put, but it also serves to redirect the file descriptors.
Remember that the stderr has the file descriptor number 2, so you can apply this.
$ exec 2> /ruta/archivo/errores.log # y luego puedes correr todas las atrocidades que quieras.
$ asdf
$ cat archivo_inexistente
$ ls archivo_inexistente
And you will not see the errors in the console, they will all be in the errors.log file that, when using cat to show your co-habit, will throw something of this style.
$ cat /ruta/de/errores.log
zsh: command not found: lasdf
zsh: command not found: asdfasd
zsh: command not found: edc
zsh: command not found: edfvrf
cat: asdfa: No such file or directory
cat: sd: No such file or directory
ls: cannot access 'ygvc': No such file or directory
What have been all the errors you've had since you redirected the terminal's stderr.
To return to normal, just rerun the exec
command redirecting the stderr to the file it was linked to, remember that it was /dev/tty3
$ exec 2> /dev/tty3
And you will see the errors in your terminal from now on.
Something I did not see mentioned is the &
symbol. This is useful in cases of verbose or silent records.
For example, to redirect both stdout and stderr to a file, this can be done.
$ comando >archivo 2>&1
$ comando &> archivo
Both forms are equivalent. And sometimes it can help to just run processes without knowing what goes on inside and knowing only the exit status. For example.
comando_o_funcion_rara &> /dev/null
if [[ "$?" == 0 ]]
then
#Código de que el programa anterior salió bien.
else
#Código de que el programa anterior salió mal.
fi
A case with which I recently found myself was when creating a system of reports that consulted a database through a proxy.
As there were many queries to make, I had a module with many editable queries on the fly, but, as often happens, I made the program very long and complex without testing every change I made until the end. The results of the queries did not come out as expected, so to debug it occurred to me to show the queries through the stderr, since the stdout of each function in each module would be required by another function that would call it, so I could not mix in the code both file descriptors or use the stdout to debug.
Everything went well, I got the answers (erroneous) of the consultations to the db and their corresponding consultations without interfering, but they were so many queries and so many data that I needed to see them at the same time and slowly. So I "piped" the output to less
but only showed me the data and not the queries ... of course, I piped the stdout of the system to less
and the queries went to the stderr, so I redirected the stderr to the stdout and then passed it through less
.
$ programa 2>&1 | less
That is, when connecting programs or commands through pipes, they do not connect anymore, but rather their file descriptors communicate with each other, and if you do not specify one, the program on the left redirects your stdout to the stdin of the right, and so on consecutively. And the stderr would never propagate through these.
Another use that you can give is the following:
$ comando1 | comando2 2> /dev/null | comando3
# | |___ Este comando corre bien
# |__________________Este no arroja nada por su stderr así que
# no habrá confusiones cuando termine la
# ejecución de toda la línea.