When you redirect a command list that contains an exec redirection, the exec >/dev/null doesn't seem to still be applied afterwards, such as with:{ exec >/dev/null; } >/dev/null; echo HiHi is printed.I was under the impression that {} command list is not considered a subshell unless it is part of a pipeline, so the exec >/dev/null should still be applied within the current shell environment in my mind.Now if you change it to:{ exec >/dev/null; } 2>/dev/null; echo Hithere is no output as expected; file descriptor 1 remains pointed at /dev/null for future commands as well. This is shown by rerunning:{ exec >/dev/null; } >/dev/null; echo Hiwhich will give no output.I tried making a script and stracing it, but I am still unsure exactly what is happening here.At each point in this script what is happening to the STDOUT file descriptor?EDIT:Adding my strace output:read(255, #!/usr/bin/env bash\n{ exec 1>/de..., 65) = 65open(/dev/null, O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3fcntl(1, F_GETFD)                       = 0fcntl(1, F_DUPFD, 10)                   = 10fcntl(1, F_GETFD)                       = 0fcntl(10, F_SETFD, FD_CLOEXEC)          = 0dup2(3, 1)                              = 1close(3)                                = 0close(10)                               = 0open(/dev/null, O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3fcntl(1, F_GETFD)                       = 0fcntl(1, F_DUPFD, 10)                   = 10fcntl(1, F_GETFD)                       = 0fcntl(10, F_SETFD, FD_CLOEXEC)          = 0dup2(3, 1)                              = 1close(3)                                = 0dup2(10, 1)                             = 1fcntl(10, F_GETFD)                      = 0x1 (flags FD_CLOEXEC)close(10)                               = 0fstat(1, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 3), ...}) = 0ioctl(1, TCGETS, 0x7ffee027ef90)        = -1 ENOTTY (Inappropriate ioctl for device)write(1, hi\n, 3)                     = 3
In the code { exec >/dev/null; } >/dev/null what is happening under the hood?
bash;shell;command line;io redirection;file descriptors
Let's follow{ exec >/dev/null; } >/dev/null; echo Histep by step.There are two commands:a. { exec >/dev/null; } >/dev/null, followed byb. echo HiThe shell executes first the command (a) and then the command (b).The execution of { exec >/dev/null; } >/dev/null proceeds as follows:a. First, the shell perform the redirection >/dev/null and remembers to undo it when the command ends.b. Then, the shell executes { exec >/dev/null; }.c. Finally, the shell switches standard output back to where is was. (This is the same mechanism as in ls -lR /usr/share/fonts >~/FontList.txt -- redirections are made only for the duration of the command to which they belong.)Once the first command is done the shell executes echo Hi. Standard output is wherever it was before the first command.