前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >无法获取指向控制台的文件描述符 (couldn't get a file descriptor referring to the console)

无法获取指向控制台的文件描述符 (couldn't get a file descriptor referring to the console)

作者头像
海海
发布于 2022-08-31 02:19:55
发布于 2022-08-31 02:19:55
3.7K00
代码可运行
举报
文章被收录于专栏:goodcitizengoodcitizen
运行总次数:0
代码可运行

背景

最近收拾东西,从一堆杂物里翻出来尘封四年多的树莓派 3B 主机来,打扫打扫灰尘,接上电源,居然还能通过之前设置好的 VNC 连上。欣慰之余,开始 clone 我的 git 项目,为它们拓展一个新的平台。在执行 cnblogs 项目 (参考《博客园排名预测 》) 对应的绘图命令时,趋势图、预测图是生成了,但没有自动打开图片,这个问题经过一番探索居然解决了,这篇文章就来分享一下解决问题的过程。

问题

第一眼看到的错误信息:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ open ./fit.png
无法获取指向控制台的文件描述符

这里我设置了控制台 locale 为中文,如果是英文的话,得到下面的结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Couldn't get a file descriptor referring to the console

果断在网上搜索了这个错误,得到的结果比较少,根据解决方案主要分以下几种:

这里我并没有调用 setfont 或 loadkeys 命令,直接执行它俩也会报一样的错误,难道需要在登录脚本里执行一下?抱着试试看的态度,我在 ~/.bashrc 中加了这么一句:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
loadkeys

重启树莓派,这回用 ssh 登录,结果一上来就报错:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sun Aug  8 23:07:46 2021 from 192.168.1.118
无法获取指向控制台的文件描述符

看来网上的说法和我遇到的不一样,只能自己探索了。好在遇事不决、量子力学,哦 no,strace,看看底层调用哪个环节出问题了:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ strace open ./fit.png
execve("/bin/open", ["open", "fit.png"], [/* 36 vars */]) = 0
brk(0)                                  = 0x822000
uname({sys="Linux", node="raspberrypi", ...}) = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x76f91000
access("/etc/ld.so.preload", R_OK)      = 0
open("/etc/ld.so.preload", O_RDONLY|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=42, ...}) = 0
mmap2(NULL, 42, PROT_READ|PROT_WRITE, MAP_PRIVATE, 3, 0) = 0x76f90000
close(3)                                = 0
open("/usr/lib/arm-linux-gnueabihf/libarmmem.so", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0h\5\0\0004\0\0\0"..., 512) = 512
lseek(3, 17960, SEEK_SET)               = 17960
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 960) = 960
lseek(3, 17696, SEEK_SET)               = 17696
read(3, "A.\0\0\0aeabi\0\1$\0\0\0\0056\0\6\6\10\1\t\1\n\3\f\1\22\4\24"..., 47) = 47
fstat64(3, {st_mode=S_IFREG|0644, st_size=18920, ...}) = 0
mmap2(NULL, 83236, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x76f4f000
mprotect(0x76f54000, 61440, PROT_NONE)  = 0
mmap2(0x76f63000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x4000) = 0x76f63000
mprotect(0x7eb5f000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC|PROT_GROWSDOWN) = 0
close(3)                                = 0
munmap(0x76f90000, 42)                  = 0
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=76981, ...}) = 0
mmap2(NULL, 76981, PROT_READ, MAP_PRIVATE, 3, 0) = 0x76f3c000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/arm-linux-gnueabihf/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0L\204\1\0004\0\0\0"..., 512) = 512
lseek(3, 1239936, SEEK_SET)             = 1239936
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 2840) = 2840
lseek(3, 1236500, SEEK_SET)             = 1236500
read(3, "A.\0\0\0aeabi\0\1$\0\0\0\0056\0\6\6\10\1\t\1\n\2\22\4\23\1\24"..., 47) = 47
fstat64(3, {st_mode=S_IFREG|0755, st_size=1242776, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x76f90000
mmap2(NULL, 1312152, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x76dfb000
mprotect(0x76f26000, 65536, PROT_NONE)  = 0
mmap2(0x76f36000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x12b000) = 0x76f36000
mmap2(0x76f39000, 9624, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x76f39000
close(3)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x76f8f000
set_tls(0x76f8f4c0, 0x76f8fba8, 0x76f94050, 0x76f8f4c0, 0x76f94050) = 0
mprotect(0x76f36000, 8192, PROT_READ)   = 0
mprotect(0x76f4f000, 20480, PROT_READ|PROT_WRITE) = 0
mprotect(0x76f4f000, 20480, PROT_READ|PROT_EXEC) = 0
cacheflush(0x76f4f000, 0x76f54000, 0, 0x15, 0x7eb5f0b0) = 0
mprotect(0x22000, 4096, PROT_READ)      = 0
mprotect(0x76f93000, 4096, PROT_READ)   = 0
munmap(0x76f3c000, 76981)               = 0
brk(0)                                  = 0x822000
brk(0x843000)                           = 0x843000
open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=4395328, ...}) = 0
mmap2(NULL, 2097152, PROT_READ, MAP_PRIVATE, 3, 0) = 0x76bfb000
mmap2(NULL, 1720320, PROT_READ, MAP_PRIVATE, 3, 0x28e000) = 0x76a57000
close(3)                                = 0
fstat64(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
fstat64(1, {st_mode=S_IFREG|0644, st_size=3753, ...}) = 0
fstat64(2, {st_mode=S_IFREG|0644, st_size=3811, ...}) = 0
open("/proc/self/fd/0", O_RDWR)         = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(3, KDGKBTYPE, 0x7eb5f14b)         = -1 ENOTTY (Inappropriate ioctl for device)
close(3)                                = 0
open("/dev/tty", O_RDWR)                = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(3, KDGKBTYPE, 0x7eb5f14b)         = -1 ENOTTY (Inappropriate ioctl for device)
close(3)                                = 0
open("/dev/tty0", O_RDWR)               = -1 EACCES (Permission denied)
open("/dev/tty0", O_WRONLY)             = -1 EACCES (Permission denied)
open("/dev/tty0", O_RDONLY)             = -1 EACCES (Permission denied)
open("/dev/vc/0", O_RDWR)               = -1 ENOENT (No such file or directory)
open("/dev/vc/0", O_WRONLY)             = -1 ENOENT (No such file or directory)
open("/dev/vc/0", O_RDONLY)             = -1 ENOENT (No such file or directory)
open("/dev/systty", O_RDWR)             = -1 ENOENT (No such file or directory)
open("/dev/systty", O_WRONLY)           = -1 ENOENT (No such file or directory)
open("/dev/systty", O_RDONLY)           = -1 ENOENT (No such file or directory)
open("/dev/console", O_RDWR)            = -1 EACCES (Permission denied)
open("/dev/console", O_WRONLY)          = -1 EACCES (Permission denied)
open("/dev/console", O_RDONLY)          = -1 EACCES (Permission denied)
ioctl(0, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, KDGKBTYPE, 0x7eb5f14b)         = -1 ENOTTY (Inappropriate ioctl for device)
ioctl(1, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, 0x7eb5f0cc) = -1 ENOTTY (Inappropriate ioctl for device)
ioctl(2, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, 0x7eb5f0cc) = -1 ENOTTY (Inappropriate ioctl for device)
open("/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
fcntl64(3, F_GETFD)                     = 0x1 (flags FD_CLOEXEC)
fstat64(3, {st_mode=S_IFREG|0644, st_size=2492, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x76f8e000
read(3, "# Locale name alias data base.\n#"..., 4096) = 2492
read(3, "", 4096)                       = 0
close(3)                                = 0
munmap(0x76f8e000, 4096)                = 0
open("/usr/share/locale/zh_CN.UTF-8/LC_MESSAGES/kbd.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/zh_CN.utf8/LC_MESSAGES/kbd.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/zh_CN/LC_MESSAGES/kbd.mo", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=30170, ...}) = 0
mmap2(NULL, 30170, PROT_READ, MAP_PRIVATE, 3, 0) = 0x76f87000
close(3)                                = 0
open("/usr/lib/arm-linux-gnueabihf/gconv/gconv-modules.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=26262, ...}) = 0
mmap2(NULL, 26262, PROT_READ, MAP_SHARED, 3, 0) = 0x76f48000
close(3)                                = 0
write(2, "\346\227\240\346\263\225\350\216\267\345\217\226\346\214\207\345\220\221\346\216\247\345\210\266\345\217\260\347\232\204\346\226"..., 46无法获取指向控制台的文件描述符
) = 46
exit_group(1)                           = ?
+++ exited with 1 +++

brk (line 53) 之前的输出都不用看,属于程序初始化的逻辑;值得注意的报错点在 line 70 与 79:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
open("/dev/console", O_RDWR)            = -1 EACCES (Permission denied)

这两个地方错误相似,都是打开 tty 设备时没有权限,而且是试了三种权限都失败了,分别为:读写 (O_RDWR)、只写 (O_WRONLY)、只读 (O_RDONLY),看来为了打开这个设备,open 也是尽力了呀~

为什么好端端的会没有权限呢?让我们看下 ls 的输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ ls -lh /dev/console
crw------- 1 root root 5, 1 Aug  8 22:37 /dev/console

 这个设备是 root 创建、root 拥有、且没有给其它用户开放任何权限,难怪会加载失败。

解决方案

既然根因是权限导致的,那就从权限入手来解决,之前系统总结过 linux 文件权限的规则 (参考 《[apue] linux 文件访问权限那些事儿 》),要将 root 创建的文件分享给当前用户访问,也不是什么难事。

console group

第一个冒出来的想法,就是创建一个新的用户组 (例如 console),把 root 和当前用户 pi 都加入到这个组中,然后指定设备的所有组为 console,并开放适当的组权限,这样就可以实现共享啦。有的人可能觉得麻烦,直接把出错的 tty 设备 chown 到当前用户不就行了?对于普通的数据文件,我也经常这样搞,但是对于公共的、系统相关的文件,我劝大家还是不要这么自信,否则可能搞到开不了机 (个人惨痛遭遇就不展开了)。另外这样做还有个额外的好处,就是当新用户遇到了同样问题时,只要把他加入这个组 (console) 就搞定了!下面是对应的脚本:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
groups
sudo groupadd console
usermod -a -G console pi
groups
su
groups
usermod -a -G console root
groups
chgrp console /dev/console
chmod g+rw /dev/console
exit

夹在 usermod 前后的 groups 命令用来显示当前用户所属的用户组,用以验证添加附加组是否成功 (实际上无效,见后面说明)。注意对 root 帐户的操作需要使用 su 切换,切换后顺便对它拥有的文件 (/dev/console) 进行操作,以避免权限上的错误,最后执行完成后 exit 退回到当前用户。这里有两个点需要注意:

  • usermod -a 选项必需和 -G 配合使用,之前我单独使用 -a 时 usemod 会直接打印 Usage,查了下 man 才弄明白;
  • 将用户添加到一个组后 groups 不能立即看到结果,必需重新登录才会生效。特别对于 VNC 登录,logout 菜单似乎不起作用,需要重启设备才行。

觉得敲命令麻烦的同学,也可以直接进入 /etc/group 文件进行修改:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ tail /etc/group
avahi:x:110:
ntp:x:111:
ssh:x:112:
bluetooth:x:113:
spi:x:999:pi
i2c:x:998:pi
gpio:x:997:pi
lightdm:x:114:
lpadmin:x:115:
console:x:1001:pi,root

 最后一行就是了。下面是执行成功后新的 ls 的输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# ls -lh /dev/console
crw-rw---- 1 root console 5, 1 Aug  8 22:37 /dev/console

此时再运行一次 strace open,发现针对 console 的访问成功了!

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
open("/dev/console", O_RDWR)            = 3

虽然因为其它 tty 没有修改仍然出错了,但是至少证明方向是对的。

tty group

上面的方案是可行的,在查看 tty 设备时无意间得到了下面的输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ ls -lh /dev/tty[0-9]*
crw------- 1 root root 4,  0 Aug  8 23:51 /dev/tty0
crw------- 1 pi   tty  4,  1 Aug  8 23:52 /dev/tty1
crw------- 1 root tty  4, 10 Aug  8 23:51 /dev/tty10
crw------- 1 root tty  4, 11 Aug  8 23:51 /dev/tty11
crw------- 1 root tty  4, 12 Aug  8 23:51 /dev/tty12
crw------- 1 root tty  4, 13 Aug  8 23:51 /dev/tty13
crw------- 1 root tty  4, 14 Aug  8 23:51 /dev/tty14
crw------- 1 root tty  4, 15 Aug  8 23:51 /dev/tty15
crw------- 1 root tty  4, 16 Aug  8 23:51 /dev/tty16
crw------- 1 root tty  4, 17 Aug  8 23:51 /dev/tty17
crw------- 1 root tty  4, 18 Aug  8 23:51 /dev/tty18
crw------- 1 root tty  4, 19 Aug  8 23:51 /dev/tty19
crw------- 1 root root 4,  2 Aug  8 23:51 /dev/tty2
crw------- 1 root tty  4, 20 Aug  8 23:51 /dev/tty20
crw------- 1 root tty  4, 21 Aug  8 23:51 /dev/tty21
crw------- 1 root tty  4, 22 Aug  8 23:51 /dev/tty22
crw------- 1 root tty  4, 23 Aug  8 23:51 /dev/tty23
crw------- 1 root tty  4, 24 Aug  8 23:51 /dev/tty24
crw------- 1 root tty  4, 25 Aug  8 23:51 /dev/tty25
crw------- 1 root tty  4, 26 Aug  8 23:51 /dev/tty26
crw------- 1 root tty  4, 27 Aug  8 23:51 /dev/tty27
crw------- 1 root tty  4, 28 Aug  8 23:51 /dev/tty28
crw------- 1 root tty  4, 29 Aug  8 23:51 /dev/tty29
crw------- 1 root root 4,  3 Aug  8 23:51 /dev/tty3
crw------- 1 root tty  4, 30 Aug  8 23:51 /dev/tty30
crw------- 1 root tty  4, 31 Aug  8 23:51 /dev/tty31
crw------- 1 root tty  4, 32 Aug  8 23:51 /dev/tty32
crw------- 1 root tty  4, 33 Aug  8 23:51 /dev/tty33
crw------- 1 root tty  4, 34 Aug  8 23:51 /dev/tty34
crw------- 1 root tty  4, 35 Aug  8 23:51 /dev/tty35
crw------- 1 root tty  4, 36 Aug  8 23:51 /dev/tty36
crw------- 1 root tty  4, 37 Aug  8 23:51 /dev/tty37
crw------- 1 root tty  4, 38 Aug  8 23:51 /dev/tty38
crw------- 1 root tty  4, 39 Aug  8 23:51 /dev/tty39
crw------- 1 root tty  4,  4 Aug  8 23:51 /dev/tty4
crw------- 1 root tty  4, 40 Aug  8 23:51 /dev/tty40
crw------- 1 root tty  4, 41 Aug  8 23:51 /dev/tty41
crw------- 1 root tty  4, 42 Aug  8 23:51 /dev/tty42
crw------- 1 root tty  4, 43 Aug  8 23:51 /dev/tty43
crw------- 1 root tty  4, 44 Aug  8 23:51 /dev/tty44
crw------- 1 root tty  4, 45 Aug  8 23:51 /dev/tty45
crw------- 1 root tty  4, 46 Aug  8 23:51 /dev/tty46
crw------- 1 root tty  4, 47 Aug  8 23:51 /dev/tty47
crw------- 1 root tty  4, 48 Aug  8 23:51 /dev/tty48
crw------- 1 root tty  4, 49 Aug  8 23:51 /dev/tty49
crw------- 1 root tty  4,  5 Aug  8 23:51 /dev/tty5
crw------- 1 root tty  4, 50 Aug  8 23:51 /dev/tty50
crw------- 1 root tty  4, 51 Aug  8 23:51 /dev/tty51
crw------- 1 root tty  4, 52 Aug  8 23:51 /dev/tty52
crw------- 1 root tty  4, 53 Aug  8 23:51 /dev/tty53
crw------- 1 root tty  4, 54 Aug  8 23:51 /dev/tty54
crw------- 1 root tty  4, 55 Aug  8 23:51 /dev/tty55
crw------- 1 root tty  4, 56 Aug  8 23:51 /dev/tty56
crw------- 1 root tty  4, 57 Aug  8 23:51 /dev/tty57
crw------- 1 root tty  4, 58 Aug  8 23:51 /dev/tty58
crw------- 1 root tty  4, 59 Aug  8 23:51 /dev/tty59
crw------- 1 root tty  4,  6 Aug  8 23:51 /dev/tty6
crw------- 1 root tty  4, 60 Aug  8 23:51 /dev/tty60
crw------- 1 root tty  4, 61 Aug  8 23:51 /dev/tty61
crw------- 1 root tty  4, 62 Aug  8 23:51 /dev/tty62
crw------- 1 root tty  4, 63 Aug  8 23:51 /dev/tty63
crw------- 1 root tty  4,  7 Aug  8 23:51 /dev/tty7
crw------- 1 root tty  4,  8 Aug  8 23:51 /dev/tty8
crw------- 1 root tty  4,  9 Aug  8 23:51 /dev/tty9

除了 tty0 / tty2 / tty3 的用户组属于 root 外,其它 tty 设备都属于 tty 用户组,原来系统早为它们准备了现成的组,我在上面创建 console 组就显得画蛇添足了,而且观察用户 pi 所属的附加组:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ groups
pi adm tty dialout cdrom sudo audio video plugdev games users input netdev gpio i2c spi console

其中一个就是 tty,所以我从善如流的决定使用使用 tty 了。因此上节的脚本可以简化为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
su
chgrp tty /dev/console /dev/tty[0-9]*
chmod g+rw /dev/console /dev/tty[0-9]*
exit

什么创建用户组、为用户添加附加组统统可以不要了,只需要修正 tty 设备文件的用户组就可以啦。

group permission

重启设备让修改生效后,再运行一次 strace open,发现还是有问题:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ strace open ./fit.png
execve("/bin/open", ["open", "./fit.png"], [/* 36 vars */]) = 0
brk(0)                                  = 0xe6b000
uname({sys="Linux", node="raspberrypi", ...}) = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x76f95000
access("/etc/ld.so.preload", R_OK)      = 0
open("/etc/ld.so.preload", O_RDONLY|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=42, ...}) = 0
mmap2(NULL, 42, PROT_READ|PROT_WRITE, MAP_PRIVATE, 3, 0) = 0x76f94000
close(3)                                = 0
open("/usr/lib/arm-linux-gnueabihf/libarmmem.so", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0h\5\0\0004\0\0\0"..., 512) = 512
lseek(3, 17960, SEEK_SET)               = 17960
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 960) = 960
lseek(3, 17696, SEEK_SET)               = 17696
read(3, "A.\0\0\0aeabi\0\1$\0\0\0\0056\0\6\6\10\1\t\1\n\3\f\1\22\4\24"..., 47) = 47
fstat64(3, {st_mode=S_IFREG|0644, st_size=18920, ...}) = 0
mmap2(NULL, 83236, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x76f53000
mprotect(0x76f58000, 61440, PROT_NONE)  = 0
mmap2(0x76f67000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x4000) = 0x76f67000
mprotect(0x7e817000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC|PROT_GROWSDOWN) = 0
close(3)                                = 0
munmap(0x76f94000, 42)                  = 0
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=76981, ...}) = 0
mmap2(NULL, 76981, PROT_READ, MAP_PRIVATE, 3, 0) = 0x76f40000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/arm-linux-gnueabihf/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0L\204\1\0004\0\0\0"..., 512) = 512
lseek(3, 1239936, SEEK_SET)             = 1239936
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 2840) = 2840
lseek(3, 1236500, SEEK_SET)             = 1236500
read(3, "A.\0\0\0aeabi\0\1$\0\0\0\0056\0\6\6\10\1\t\1\n\2\22\4\23\1\24"..., 47) = 47
fstat64(3, {st_mode=S_IFREG|0755, st_size=1242776, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x76f94000
mmap2(NULL, 1312152, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x76dff000
mprotect(0x76f2a000, 65536, PROT_NONE)  = 0
mmap2(0x76f3a000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x12b000) = 0x76f3a000
mmap2(0x76f3d000, 9624, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x76f3d000
close(3)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x76f93000
set_tls(0x76f934c0, 0x76f93ba8, 0x76f98050, 0x76f934c0, 0x76f98050) = 0
mprotect(0x76f3a000, 8192, PROT_READ)   = 0
mprotect(0x76f53000, 20480, PROT_READ|PROT_WRITE) = 0
mprotect(0x76f53000, 20480, PROT_READ|PROT_EXEC) = 0
cacheflush(0x76f53000, 0x76f58000, 0, 0x15, 0x7e8170b0) = 0
mprotect(0x22000, 4096, PROT_READ)      = 0
mprotect(0x76f97000, 4096, PROT_READ)   = 0
munmap(0x76f40000, 76981)               = 0
brk(0)                                  = 0xe6b000
brk(0xe8c000)                           = 0xe8c000
open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=4395328, ...}) = 0
mmap2(NULL, 2097152, PROT_READ, MAP_PRIVATE, 3, 0) = 0x76bff000
mmap2(NULL, 1720320, PROT_READ, MAP_PRIVATE, 3, 0x28e000) = 0x76a5b000
close(3)                                = 0
fstat64(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
fstat64(1, {st_mode=S_IFREG|0644, st_size=3755, ...}) = 0
fstat64(2, {st_mode=S_IFREG|0644, st_size=3813, ...}) = 0
open("/proc/self/fd/0", O_RDWR)         = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(3, KDGKBTYPE, 0x7e81714b)         = -1 ENOTTY (Inappropriate ioctl for device)
close(3)                                = 0
open("/dev/tty", O_RDWR)                = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(3, KDGKBTYPE, 0x7e81714b)         = -1 ENOTTY (Inappropriate ioctl for device)
close(3)                                = 0
open("/dev/tty0", O_RDWR)               = -1 EACCES (Permission denied)
open("/dev/tty0", O_WRONLY)             = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 -opost -isig -icanon -echo ...}) = 0
ioctl(3, KDGKBTYPE, 0x7e81714b)         = 0
ioctl(3, VT_GETSTATE, 0x7e8171a8)       = 0
ioctl(3, VIDIOC_QUERYCAP or VT_OPENQRY, 0x7e8171a4) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x76f93068) = 1882
exit_group(0)                           = ?
+++ exited with 0 +++
open: Unable to open /dev/tty2: 权限不够

line 70 有一次失败,但是马上 line 71 对同一个设备操作成功,末尾出现的权限不够失败对应的 /dev/tty2 文件根本在前面没有出现过,amazing~

用 ls 大法看一看:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ ls -lh /dev/tty[0-9]*
crw--w---- 1 root tty 4,  0 Aug  9 00:13 /dev/tty0
crw------- 1 pi   tty 4,  1 Aug  9 00:14 /dev/tty1
crw--w---- 1 root tty 4, 10 Aug  9 00:13 /dev/tty10
crw--w---- 1 root tty 4, 11 Aug  9 00:13 /dev/tty11
crw--w---- 1 root tty 4, 12 Aug  9 00:13 /dev/tty12
crw--w---- 1 root tty 4, 13 Aug  9 00:13 /dev/tty13
crw--w---- 1 root tty 4, 14 Aug  9 00:13 /dev/tty14
crw--w---- 1 root tty 4, 15 Aug  9 00:13 /dev/tty15
crw--w---- 1 root tty 4, 16 Aug  9 00:13 /dev/tty16
crw--w---- 1 root tty 4, 17 Aug  9 00:13 /dev/tty17
crw--w---- 1 root tty 4, 18 Aug  9 00:13 /dev/tty18
crw--w---- 1 root tty 4, 19 Aug  9 00:13 /dev/tty19
crw--w---- 1 root tty 4,  2 Aug  9 00:13 /dev/tty2
crw--w---- 1 root tty 4, 20 Aug  9 00:13 /dev/tty20
crw--w---- 1 root tty 4, 21 Aug  9 00:13 /dev/tty21
crw--w---- 1 root tty 4, 22 Aug  9 00:13 /dev/tty22
crw--w---- 1 root tty 4, 23 Aug  9 00:13 /dev/tty23
crw--w---- 1 root tty 4, 24 Aug  9 00:13 /dev/tty24
crw--w---- 1 root tty 4, 25 Aug  9 00:13 /dev/tty25
crw--w---- 1 root tty 4, 26 Aug  9 00:13 /dev/tty26
crw--w---- 1 root tty 4, 27 Aug  9 00:13 /dev/tty27
crw--w---- 1 root tty 4, 28 Aug  9 00:13 /dev/tty28
crw--w---- 1 root tty 4, 29 Aug  9 00:13 /dev/tty29
crw--w---- 1 root tty 4,  3 Aug  9 00:13 /dev/tty3
crw--w---- 1 root tty 4, 30 Aug  9 00:13 /dev/tty30
crw--w---- 1 root tty 4, 31 Aug  9 00:13 /dev/tty31
crw--w---- 1 root tty 4, 32 Aug  9 00:13 /dev/tty32
crw--w---- 1 root tty 4, 33 Aug  9 00:13 /dev/tty33
crw--w---- 1 root tty 4, 34 Aug  9 00:13 /dev/tty34
crw--w---- 1 root tty 4, 35 Aug  9 00:13 /dev/tty35
crw--w---- 1 root tty 4, 36 Aug  9 00:13 /dev/tty36
crw--w---- 1 root tty 4, 37 Aug  9 00:13 /dev/tty37
crw--w---- 1 root tty 4, 38 Aug  9 00:13 /dev/tty38
crw--w---- 1 root tty 4, 39 Aug  9 00:13 /dev/tty39
crw--w---- 1 root tty 4,  4 Aug  9 00:13 /dev/tty4
crw--w---- 1 root tty 4, 40 Aug  9 00:13 /dev/tty40
crw--w---- 1 root tty 4, 41 Aug  9 00:13 /dev/tty41
crw--w---- 1 root tty 4, 42 Aug  9 00:13 /dev/tty42
crw--w---- 1 root tty 4, 43 Aug  9 00:13 /dev/tty43
crw--w---- 1 root tty 4, 44 Aug  9 00:13 /dev/tty44
crw--w---- 1 root tty 4, 45 Aug  9 00:13 /dev/tty45
crw--w---- 1 root tty 4, 46 Aug  9 00:13 /dev/tty46
crw--w---- 1 root tty 4, 47 Aug  9 00:13 /dev/tty47
crw--w---- 1 root tty 4, 48 Aug  9 00:13 /dev/tty48
crw--w---- 1 root tty 4, 49 Aug  9 00:13 /dev/tty49
crw--w---- 1 root tty 4,  5 Aug  9 00:13 /dev/tty5
crw--w---- 1 root tty 4, 50 Aug  9 00:13 /dev/tty50
crw--w---- 1 root tty 4, 51 Aug  9 00:13 /dev/tty51
crw--w---- 1 root tty 4, 52 Aug  9 00:13 /dev/tty52
crw--w---- 1 root tty 4, 53 Aug  9 00:13 /dev/tty53
crw--w---- 1 root tty 4, 54 Aug  9 00:13 /dev/tty54
crw--w---- 1 root tty 4, 55 Aug  9 00:13 /dev/tty55
crw--w---- 1 root tty 4, 56 Aug  9 00:13 /dev/tty56
crw--w---- 1 root tty 4, 57 Aug  9 00:13 /dev/tty57
crw--w---- 1 root tty 4, 58 Aug  9 00:13 /dev/tty58
crw--w---- 1 root tty 4, 59 Aug  9 00:13 /dev/tty59
crw--w---- 1 root tty 4,  6 Aug  9 00:13 /dev/tty6
crw--w---- 1 root tty 4, 60 Aug  9 00:13 /dev/tty60
crw--w---- 1 root tty 4, 61 Aug  9 00:13 /dev/tty61
crw--w---- 1 root tty 4, 62 Aug  9 00:13 /dev/tty62
crw--w---- 1 root tty 4, 63 Aug  9 00:13 /dev/tty63
crw--w---- 1 root tty 4,  7 Aug  9 00:13 /dev/tty7
crw--w---- 1 root tty 4,  8 Aug  9 00:13 /dev/tty8
crw--w---- 1 root tty 4,  9 Aug  9 00:13 /dev/tty9

所有 tty 设置的组权限变成了只写?难道是上一步中重启设备前我忘了设置各个文件的权限? 用 root 帐号 chmod 一下,输出这次正常了:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ strace open ./fit.png
execve("/bin/open", ["open", "./fit.png"], [/* 36 vars */]) = 0
brk(0)                                  = 0x288000
uname({sys="Linux", node="raspberrypi", ...}) = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x76efd000
access("/etc/ld.so.preload", R_OK)      = 0
open("/etc/ld.so.preload", O_RDONLY|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=42, ...}) = 0
mmap2(NULL, 42, PROT_READ|PROT_WRITE, MAP_PRIVATE, 3, 0) = 0x76efc000
close(3)                                = 0
open("/usr/lib/arm-linux-gnueabihf/libarmmem.so", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0h\5\0\0004\0\0\0"..., 512) = 512
lseek(3, 17960, SEEK_SET)               = 17960
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 960) = 960
lseek(3, 17696, SEEK_SET)               = 17696
read(3, "A.\0\0\0aeabi\0\1$\0\0\0\0056\0\6\6\10\1\t\1\n\3\f\1\22\4\24"..., 47) = 47
fstat64(3, {st_mode=S_IFREG|0644, st_size=18920, ...}) = 0
mmap2(NULL, 83236, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x76ebb000
mprotect(0x76ec0000, 61440, PROT_NONE)  = 0
mmap2(0x76ecf000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x4000) = 0x76ecf000
mprotect(0x7ea80000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC|PROT_GROWSDOWN) = 0
close(3)                                = 0
munmap(0x76efc000, 42)                  = 0
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=76981, ...}) = 0
mmap2(NULL, 76981, PROT_READ, MAP_PRIVATE, 3, 0) = 0x76ea8000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/arm-linux-gnueabihf/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0L\204\1\0004\0\0\0"..., 512) = 512
lseek(3, 1239936, SEEK_SET)             = 1239936
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 2840) = 2840
lseek(3, 1236500, SEEK_SET)             = 1236500
read(3, "A.\0\0\0aeabi\0\1$\0\0\0\0056\0\6\6\10\1\t\1\n\2\22\4\23\1\24"..., 47) = 47
fstat64(3, {st_mode=S_IFREG|0755, st_size=1242776, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x76efc000
mmap2(NULL, 1312152, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x76d67000
mprotect(0x76e92000, 65536, PROT_NONE)  = 0
mmap2(0x76ea2000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x12b000) = 0x76ea2000
mmap2(0x76ea5000, 9624, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x76ea5000
close(3)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x76efb000
set_tls(0x76efb4c0, 0x76efbba8, 0x76f00050, 0x76efb4c0, 0x76f00050) = 0
mprotect(0x76ea2000, 8192, PROT_READ)   = 0
mprotect(0x76ebb000, 20480, PROT_READ|PROT_WRITE) = 0
mprotect(0x76ebb000, 20480, PROT_READ|PROT_EXEC) = 0
cacheflush(0x76ebb000, 0x76ec0000, 0, 0x15, 0x7ea800b0) = 0
mprotect(0x22000, 4096, PROT_READ)      = 0
mprotect(0x76eff000, 4096, PROT_READ)   = 0
munmap(0x76ea8000, 76981)               = 0
brk(0)                                  = 0x288000
brk(0x2a9000)                           = 0x2a9000
open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=4395328, ...}) = 0
mmap2(NULL, 2097152, PROT_READ, MAP_PRIVATE, 3, 0) = 0x76b67000
mmap2(NULL, 1720320, PROT_READ, MAP_PRIVATE, 3, 0x28e000) = 0x769c3000
close(3)                                = 0
fstat64(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
fstat64(1, {st_mode=S_IFREG|0644, st_size=3755, ...}) = 0
fstat64(2, {st_mode=S_IFREG|0644, st_size=3813, ...}) = 0
open("/proc/self/fd/0", O_RDWR)         = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(3, KDGKBTYPE, 0x7ea8014b)         = -1 ENOTTY (Inappropriate ioctl for device)
close(3)                                = 0
open("/dev/tty", O_RDWR)                = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(3, KDGKBTYPE, 0x7ea8014b)         = -1 ENOTTY (Inappropriate ioctl for device)
close(3)                                = 0
open("/dev/tty0", O_RDWR)               = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 -opost -isig -icanon -echo ...}) = 0
ioctl(3, KDGKBTYPE, 0x7ea8014b)         = 0
ioctl(3, VT_GETSTATE, 0x7ea801a8)       = 0
ioctl(3, VIDIOC_QUERYCAP or VT_OPENQRY, 0x7ea801a4) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x76efb068) = 2013
exit_group(0)                           = ?
+++ exited with 0 +++

不过再次重启后,这个文件权限仍然会被重置,之前使用 console group 时,也发现重启设备后 /dev/console 文件的用户组会自动重置为 root,组权限重置为空。好在这里只是将权限重置为只写,难道每次登录都要设置一遍 tty 文件权限?

xdg-open

答案是 no,倒不是因为找到了解决方案,而是即使在权限正确的情况下、open 不再报错了,图片还是没有自动打开 (汗)。于是我决定试试其它的命令,经过一番百度,找到了一个在 Ubuntu 下很常用的 xdg-open 命令,参数是要打开的图片路径,调用方式和 open 一样。话说回来,open 是我在 mac 上使用的命令,不适用 raspberrypi 是情理之中的,至于这个上的 open 是干啥的,我没找到对应的 man 记录 (还是个三无命令)。另外一开始如果使用 xdg-open,是不是就不用设置设备文件的用户组和权限了?没有试,不得而知。

结语

本文探索了诡异的 tty 设备文件权限问题,结合 linux 文件权限相关的知识进行了一番大胆的尝试,最后却另辟蹊径解决了问题。如果你在现实中遇到了类似的问题,不妨可以试试上面的方案,不管成功与否,都欢迎在文章下面留言反馈。

后记

和问题相关的都说的差不多了,下面来聊两句题外话。这次收拾尘封的树莓派,我深切的体会到了设置密码要简单的重要性,ssh 登录过程中试遍了我常用的所有密码,都不行,最后还是 1-6 拯救了我,而且 root 密码也是这个呦~

最后看着破破烂烂的亚克力塑料外壳,实在不能忍了,果断淘宝了一套新的外壳换上,换壳前后对比明显:

最后上一张树莓派 VNC 的截图:

参考

1. Ubuntu下通过命令打开图片

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-10-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
Linux 命令(137)—— strace 命令
strace 命令是一个集诊断、调试、统计于一体的工具,我们可以使用 strace 对程序的系统调用和信号传递的跟踪结果来对程序进行分析,以达到解决问题或者是了解程序工作过程的目的。当然strace 与专业的调试工具比如说 gdb 之类的是没法相比的,因为它不是一个专业的调试器。
恋喵大鲤鱼
2020/04/13
8.6K0
这条命令有可能断送DBA职业生涯,我今天真的执行了
这个是从库,没有读业务和其他下游同步,风险可控。但是大家还是要谨慎。我执行这个命令是因为我搜到的菜鸟教程的split命令案例错误导致我生成了大量小文件。没想到大名鼎鼎的菜鸟教程也会有问题,大家还用man或者tldr查看帮助手册吧。
DBA札记
2024/06/03
1350
这条命令有可能断送DBA职业生涯,我今天真的执行了
ls 不显示,rm 删不掉,怎么办?
有个叫atest的东西 ls -l atest 查不出来是什么 下面删也删不掉 但是可以用mv改名字,它放在/目录下,用ls /导致不能显示 如果操作,请大侠指点, 顺便问下什么时候会导致ls /   不显示,谢谢! # s
三杯水Plus
2018/11/14
1.1K0
PHP码农在Golang压力下的生存之道-PHP性能优化实践
随着国内Golang的火爆,phper的生存压力越来越大,在一次内部技术讨论中,gopher甚至提出,要什么php,写php的全部开掉,唉,码农何苦为难码农。 本文试图寻找一种有效实践,减少php web程序和golang之间的性能差距,摆脱php在公司往后只能写后台的悲惨命运。 做优化的思路 1、了解php语言特性 2、了解php的执行过程 3、压测分析性能 语言特性 PHP被称为脚本语言或解释型语言,它没有被直接编译为机器指令,而是编译为一种中间代码的形式,无法直接在CPU上执行。 所以PHP的执行需要
架构师刀哥
2018/03/20
2.3K0
故障分析 | 哪些情况下 MySQL 配置文件会被截断?
作者:龚唐杰,爱可生 DBA 团队成员,主要负责 MySQL 技术支持,擅长 MySQL、PG、国产数据库。
爱可生开源社区
2024/10/10
1830
故障分析 | 哪些情况下 MySQL 配置文件会被截断?
futex验证_fulvic
#include <semaphore.h> #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <string.h>
全栈程序员站长
2022/11/08
3140
df 和 ls 命令执行夯主
其实他说第二点问题的时候我就已经猜到问题所在了,那不就是远程挂载的磁盘非正常的掉了,然后就会造成这个问题。但是他说 ISCSI 这个玩意的时候我不知道是啥,于是查了一下,有兴趣的同学可以看看这是:https://zhuanlan.zhihu.com/p/60986068,看的出来他是一个网络存储,那么就更加坚定我的想法了,开始指挥解决问题。
张琳兮
2020/05/25
2.1K0
df 和 ls 命令执行夯主
Swoole v4.7 版本预览之支持 c-ares
c-ares 是一个异步 DNS 解析库。它适用于需要在不阻塞的情况下执行 DNS 查询或需要并行执行多个 DNS 查询的应用程序。
沈唁
2021/07/23
8170
MHA故障failover执行不成功的背后的大坑
线上环境OS为centos7.6 x64, DBA 在机房演练MHA故障切换,但每次切换脚本执行失败。
richard.xia_志培
2022/06/14
6001
MHA故障failover执行不成功的背后的大坑
十个例子让你了解 strace 的使用技巧
tcpdump 作为计算机网络排查的一大神器,掌握了上文所说的技巧,可以让你随时随地得心应手的掌握网络应用的一举一动。
用户3147702
2022/06/27
4.9K0
十个例子让你了解 strace 的使用技巧
线程的创建以及线程的本质
上节详细学习了进程的创建,通过实例学习了fork和vfork的区别。本节将学习线程的创建,只涉及应用层的线程,内核线程的创建在后面学习。
DragonKingZhu
2020/03/24
1.7K0
线程的创建以及线程的本质
使用golang的net包进行域名解析过程分析
我们都知道,在计算机的世界,建立连接都是需要依靠五元组的(源ip,源端口,目的ip,目的端口,协议),而在实际用户使用过程中,浏览器会帮我们识别和管理源ip和端口以及协议(http,https),协议确定后其实目的端口也就确定了(80或443). 因此整个DNS系统要解决的问题就是将用户在浏览器中输入的域名最终转换成可识别的目的ip,进而进行连接通信。下面以一个简单例子来分析下dns解析的过程.
BGBiao
2019/09/11
13.7K0
Linux系统下刨析hello world背后的秘密
linux系统上使用gcc生成可执行程序:gcc -g -W helloworld.c -o helloworld
Linux兵工厂
2023/02/28
6410
Linux系统下刨析hello world背后的秘密
Linux 性能调优之CPU上下文切换
99%的焦虑都来自于虚度时间和没有好好做事,所以唯一的解决办法就是行动起来,认真做完事情,战胜焦虑,战胜那些心里空荡荡的时刻,而不是选择逃避。不要站在原地想象困难,行动永远是改变现状的最佳方式
山河已无恙
2024/09/12
9130
Linux 性能调优之CPU上下文切换
JAVA中的I/O模型-BIO
上面的主文件我们只需要关注2819、2835、2836以及2844四行,前三行分别对应的是socket的创建,以及绑定端口和监听事件。而后面的poll则是一个等待事件函数,我们接下来看看方法描述。
Montos
2021/03/10
4920
JAVA中的I/O模型-BIO
CVE-2021-44731 linux snap 本地提权漏洞分析
Snap是Canonical为使用Linux内核的操作系统开发的软件打包和部署系统。这些包(称为 snaps)和使用它们的工具 snapd 可在一系列 Linux 发行版中工作。
枪哥四海为家
2022/03/05
3.5K0
CVE-2021-44731 linux snap 本地提权漏洞分析
mmap及linux地址空间随机化失效漏洞
Linux下动态库是通过mmap建立起内存和文件的映射关系。其定义如下void* mmap(void* start,size_t length,int prot,int flags,int fd,off_t offset);,在第一个参数start为NULL的时候系统会随机分配一个地址,我们可以通过示例来看mmap映射地址的流程。
WeaponX
2018/09/20
2.3K0
tools-tcp
如在我的电脑上strace -o 1.txt pkill goldendict,strace就给出了3287行的信息。。。如果加上参数-e trace=process,那么就只有4行:
Heeler-Deer
2023/02/22
4800
现代CPU性能分析与优化-性能分析方法-代码跟踪
跟踪在概念上与插桩化非常相似,但略有不同。代码插桩化假设用户可以编排他们应用程序的代码。另一方面,跟踪依赖于程序的外部依赖项的现有插桩化。例如,strace工具使我们能够跟踪系统调用,并可以被视为对Linux内核的插桩化。英特尔处理器跟踪(见附录D)使您能够记录程序执行的指令,并可以被视为对CPU的插桩化。跟踪可以从事先适当插桩化的组件中获得,并且不受更改的影响。跟踪通常被用作黑匣子方法,其中用户无法修改应用程序的代码,但他们希望了解程序在幕后执行的操作。
王很水
2024/08/19
2110
现代CPU性能分析与优化-性能分析方法-代码跟踪
linux系统编程之文件与I/O(四):文件的属性
该文章是关于Linux文件系统的一些基本概念和主要文件系统的概述。它包括关于ext2/ext3/ext4文件系统的介绍,以及如何使用fsck工具检查和修复文件系统。此外,文章还讨论了Linux中的文件权限、用户和组,以及inode和目录的概念。最后,文章介绍了如何使用Linux命令行工具进行文件系统检查和修复。
s1mba
2018/01/03
9940
相关推荐
Linux 命令(137)—— strace 命令
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档