Unexpected behavior in bash redirect

I found strange and completely unexpected behavior when working with redirection in bash and even if I manage to get around it, I would like to know why this is happening.

If I run this command: { echo wtf > /dev/stdout ; } >> wtf.txtN times, I expect to see the filled lines N "wtf". What I found in the file is one line.

I think that since the first command opens / dev / stdout in truncation mode, then the mode is inherited by the second file descriptor (wtf.txt), which is then completely erased, but I would like to know if some of you can explain this better, and if this is the correct behavior or mistake.

To be clear, the command I used was different, but with an example of an echo it is easier to understand this. The original command was a command that needs an output file as an argument, and since I want the output to stdout to pass / dev / stdout as an argument. The same behavior can be checked using the command openssl rand -hex 4 -out /dev/stdout >> wtf.txt.

Finally, the solution that I was able to solve was delegating the add operation to tee as follows: { echo wtf > /dev/stdout } | tee -a wtf.txt > /dev/null

+4
source share
1 answer

You can check what happens using strace:

strace -o wtf-trace.txt -ff bash -c '{ (echo wtf) > /dev/stdout; } >> wtf.txt'

In my case, this will lead to the creation of two files, such as wtf-trace.txt.12889and wtf-trace.txt.12890. What happens, process 1 >> wtf.txt:

open("wtf.txt", O_WRONLY|O_CREAT|O_APPEND, 0666) = 3
dup2(3, 1)                              = 1
close(3)                                = 0
clone(child_stack=0, .................) = 12890
wait4(-1, [{WIFEXITED(s) .............) = 12890
exit_group(0)                           = ?

"wtf.txt" FD 3. FD 1 FD 3 FD 3. (), .

{ echo wtf > /dev/stdout } FD 1 (stdout), :

open("/dev/stdout", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
dup2(3, 1)                              = 1
close(3)                                = 0
fstat(1, {st_mode=S_IFREG|0664, st_size=0, ...}) = 0
write(1, "wtf\n", 4)                    = 4
exit_group(0)                           = ?

, /dev/stdout (note O_TRUNC) FD 3, dup2, FD 3 FD 1, FD 3, FD 1 0 st_size=0, .

| cat >>, FD 1, , ...

NB: strace.

+1

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


All Articles