User zen_desu mentioned this bug report on the #bash IRC channel of
libera.chat today: https://github.com/desultory/ugrd/pull/328
Basically, in bash 5.3, if you try to source a /sys/block/*/uevent file;
example:
$ cat /sys/block/sda/uevent
MAJOR=8
MINOR=0
DEVNAME=sda
DEVTYPE=disk
DISKSEQ=1
source or . will fail printing the error message"bash: ${file}: Success"
$ . /sys/block/sda/uevent; printf %s\\n "$?"
bash: /sys/block/sda/uevent: Success
1
$ (set -x; . /sys/block/sda/uevent); printf %s\\n "$?"
+ . /sys/block/sda/uevent
bash: /sys/block/sda/uevent: Success
1
This happens because /sys/block/*/uevent show up as regular files, and
reports a file size of 4096 in stat:
$ stat /sys/block/sda/uevent
File: /sys/block/sda/uevent
Size: 4096 Blocks: 0 IO Block: 4096 regular file
Device: 0,21 Inode: 32211 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2025-07-12 16:08:57.424075455 +0200
Modify: 2025-07-12 16:08:57.424075455 +0200
Change: 2025-07-12 16:08:57.424075455 +0200
Birth: -
..and there is a new check in evalfile_internal() that treats like an
error to not get filesize bytes after one read from a regular file
(given a large enough buffer)
builtins/evalfile.c (80a8f650a1defc3f72539c3b57bf6d228c33c116)
157 if (S_ISREG (finfo.st_mode) && file_size <= SSIZE_MAX)
158 {
159 string = (char *)xmalloc (1 + file_size);
160 nr = read (fd, string, file_size);
161 if (nr >= 0)
162 string[nr] = '\0';
163 if (nr != file_size)
164 nr = -1; /* XXX - didn't get the whole file */
165 }
166 else
167 nr = zmapfd (fd, &string, 0);
168
169 return_val = errno;
170 close (fd);
171 errno = return_val;
172
173 if (nr < 0) /* XXX was != file_size, not < 0 */
174 {
175 free (string);
176 goto file_error_and_exit;
177 }
A workaround for this is possibly eval " $(< /sys/block/sda/uevent)" ,
but I would expect bash's source to be able these files even if they are
magic.
o/
emanuele6