Skip to main content
Became Hot Network Question
added 60 characters in body
Source Link
terdon
  • 252.2k
  • 69
  • 480
  • 718

I observe that, on Ubuntu 24.04.2 with coreutils version 9.4-3ubuntu6, running:

$ tail -c 4097 /dev/zero
$ echo $?
0

exits immediately with a status code of 0. I expected the command to block indefinitely since /dev/zero is an endless stream.

In contrast, the following commands behave as expected (i.e., they block until interrupted):

$ tail -c 4096 /dev/zero
^C
$ echo $?
130
$ cat /dev/zero | tail -c 4097
^C
$ echo $?
130

Debug attempt

The strace output shows differences between the two invocations:

strace tail -c 4096 /dev/zero strace tail -c 4097 /dev/zero
close(3) = 0 close(3) = 0
openat(AT_FDCWD, "/dev/zero", O_RDONLY) = 3 openat(AT_FDCWD, "/dev/zero", O_RDONLY) = 3
fstat(3, {st_mode=S_IFCHR|0666, st_rdev=makedev(0x1, 0x5), …}) = 0 fstat(3, {st_mode=S_IFCHR|0666, st_rdev=makedev(0x1, 0x5), …}) = 0
lseek(3, -4096, SEEK_END) = 0 lseek(3, -4097, SEEK_END) = 0
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 read(3, "\0\0\0\0\0\0\0\0\0\…, 4097) = 4097
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 fstat(1, {st_mode=S_IFIFO|0600, st_size=0, …}) = 0
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 write(1, "\0\0\0\0\0\0\0\0\0\…, 4096
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 close(3) = 0
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 write(1, "\0", 1) = 1
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 close(1) = 0
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 close(2) = 0
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 exit_group(0) = ?
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 ~~+~~ exited with 0 ~~+~~
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192

I observe that running:

$ tail -c 4097 /dev/zero
$ echo $?
0

exits immediately with a status code of 0. I expected the command to block indefinitely since /dev/zero is an endless stream.

In contrast, the following commands behave as expected (i.e., they block until interrupted):

$ tail -c 4096 /dev/zero
^C
$ echo $?
130
$ cat /dev/zero | tail -c 4097
^C
$ echo $?
130

Debug attempt

The strace output shows differences between the two invocations:

strace tail -c 4096 /dev/zero strace tail -c 4097 /dev/zero
close(3) = 0 close(3) = 0
openat(AT_FDCWD, "/dev/zero", O_RDONLY) = 3 openat(AT_FDCWD, "/dev/zero", O_RDONLY) = 3
fstat(3, {st_mode=S_IFCHR|0666, st_rdev=makedev(0x1, 0x5), …}) = 0 fstat(3, {st_mode=S_IFCHR|0666, st_rdev=makedev(0x1, 0x5), …}) = 0
lseek(3, -4096, SEEK_END) = 0 lseek(3, -4097, SEEK_END) = 0
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 read(3, "\0\0\0\0\0\0\0\0\0\…, 4097) = 4097
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 fstat(1, {st_mode=S_IFIFO|0600, st_size=0, …}) = 0
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 write(1, "\0\0\0\0\0\0\0\0\0\…, 4096
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 close(3) = 0
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 write(1, "\0", 1) = 1
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 close(1) = 0
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 close(2) = 0
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 exit_group(0) = ?
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 ~~+~~ exited with 0 ~~+~~
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192

I observe that, on Ubuntu 24.04.2 with coreutils version 9.4-3ubuntu6, running:

$ tail -c 4097 /dev/zero
$ echo $?
0

exits immediately with a status code of 0. I expected the command to block indefinitely since /dev/zero is an endless stream.

In contrast, the following commands behave as expected (i.e., they block until interrupted):

$ tail -c 4096 /dev/zero
^C
$ echo $?
130
$ cat /dev/zero | tail -c 4097
^C
$ echo $?
130

Debug attempt

The strace output shows differences between the two invocations:

strace tail -c 4096 /dev/zero strace tail -c 4097 /dev/zero
close(3) = 0 close(3) = 0
openat(AT_FDCWD, "/dev/zero", O_RDONLY) = 3 openat(AT_FDCWD, "/dev/zero", O_RDONLY) = 3
fstat(3, {st_mode=S_IFCHR|0666, st_rdev=makedev(0x1, 0x5), …}) = 0 fstat(3, {st_mode=S_IFCHR|0666, st_rdev=makedev(0x1, 0x5), …}) = 0
lseek(3, -4096, SEEK_END) = 0 lseek(3, -4097, SEEK_END) = 0
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 read(3, "\0\0\0\0\0\0\0\0\0\…, 4097) = 4097
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 fstat(1, {st_mode=S_IFIFO|0600, st_size=0, …}) = 0
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 write(1, "\0\0\0\0\0\0\0\0\0\…, 4096
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 close(3) = 0
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 write(1, "\0", 1) = 1
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 close(1) = 0
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 close(2) = 0
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 exit_group(0) = ?
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 ~~+~~ exited with 0 ~~+~~
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192
Source Link

Why does `tail -c 4097 /dev/zero` exit immediately instead of blocking?

I observe that running:

$ tail -c 4097 /dev/zero
$ echo $?
0

exits immediately with a status code of 0. I expected the command to block indefinitely since /dev/zero is an endless stream.

In contrast, the following commands behave as expected (i.e., they block until interrupted):

$ tail -c 4096 /dev/zero
^C
$ echo $?
130
$ cat /dev/zero | tail -c 4097
^C
$ echo $?
130

Debug attempt

The strace output shows differences between the two invocations:

strace tail -c 4096 /dev/zero strace tail -c 4097 /dev/zero
close(3) = 0 close(3) = 0
openat(AT_FDCWD, "/dev/zero", O_RDONLY) = 3 openat(AT_FDCWD, "/dev/zero", O_RDONLY) = 3
fstat(3, {st_mode=S_IFCHR|0666, st_rdev=makedev(0x1, 0x5), …}) = 0 fstat(3, {st_mode=S_IFCHR|0666, st_rdev=makedev(0x1, 0x5), …}) = 0
lseek(3, -4096, SEEK_END) = 0 lseek(3, -4097, SEEK_END) = 0
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 read(3, "\0\0\0\0\0\0\0\0\0\…, 4097) = 4097
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 fstat(1, {st_mode=S_IFIFO|0600, st_size=0, …}) = 0
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 write(1, "\0\0\0\0\0\0\0\0\0\…, 4096
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 close(3) = 0
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 write(1, "\0", 1) = 1
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 close(1) = 0
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 close(2) = 0
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 exit_group(0) = ?
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192 ~~+~~ exited with 0 ~~+~~
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192
read(3, "\0\0\0\0\0\0\0\0\00"…, 8192) = 8192