主頁 > 作業系統 > 無法獲取指向控制臺的檔案描述符 (couldn't get a file descriptor referring to the console)

無法獲取指向控制臺的檔案描述符 (couldn't get a file descriptor referring to the console)

2021-10-20 06:04:56 作業系統

背景

最近收拾東西,從一堆雜物里翻出來塵封四年多的樹莓派 3B 主機來,打掃打掃灰塵,接上電源,居然還能通過之前設定好的 VNC 連上,欣慰之余,開始 clone 我的 git 專案,為它們拓展一個新的平臺,在執行 cnblogs 專案 (參考《博客園排名預測 》) 對應的繪圖命令時,趨勢圖、預測圖是生成了,但沒有自動打開圖片,這個問題經過一番探索居然解決了,這篇文章就來分享一下解決問題的程序,

問題

第一眼看到的錯誤資訊:

$ open ./fit.png
無法獲取指向控制臺的檔案描述符

這里我設定了控制臺 locale 為中文,如果是英文的話,得到下面的結果:

Couldn't get a file descriptor referring to the console

果斷在網上搜索了這個錯誤,得到的結果比較少,根據解決方案主要分以下幾種:

  • setfont 命令:
    • fedora - 錯誤:無法獲得指向控制臺的檔案描述符
    • Error in linux console : Couldn't get a file descriptor referring to the console
  • loadkeys 命令:
    • loadkeys says “Couldn't get a file descriptor referring to the console” in chroot on ChromeOS

這里我并沒有呼叫 setfont 或 loadkeys 命令,直接執行它倆也會報一樣的錯誤,難道需要在登錄腳本里執行一下?抱著試試看的態度,我在 ~/.bashrc 中加了這么一句:

loadkeys

重啟樹莓派,這回用 ssh 登錄,結果一上來就報錯:

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,看看底層呼叫哪個環節出問題了:

$ 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:

open("/dev/console", O_RDWR)            = -1 EACCES (Permission denied)

這兩個地方錯誤相似,都是打開 tty 設備時沒有權限,而且是試了三種權限都失敗了,分別為:讀寫 (O_RDWR)、只寫 (O_WRONLY)、只讀 (O_RDONLY),看來為了打開這個設備,open 也是盡力了呀~

為什么好端端的會沒有權限呢?讓我們看下 ls 的輸出:

$ 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) 就搞定了!下面是對應的腳本:

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 檔案進行修改:

$ 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 的輸出:

# ls -lh /dev/console
crw-rw---- 1 root console 5, 1 Aug  8 22:37 /dev/console

此時再運行一次 strace open,發現針對 console 的訪問成功了!

open("/dev/console", O_RDWR)            = 3

雖然因為其它 tty 沒有修改仍然出錯了,但是至少證明方向是對的,

tty group

上面的方案是可行的,在查看 tty 設備時無意間得到了下面的輸出:

$ 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 所屬的附加組:

$ groups
pi adm tty dialout cdrom sudo audio video plugdev games users input netdev gpio i2c spi console

其中一個就是 tty,所以我從善如流的決定使用使用 tty 了,因此上節的腳本可以簡化為:

su
chgrp tty /dev/console /dev/tty[0-9]*
chmod g+rw /dev/console /dev/tty[0-9]*
exit

什么創建用戶組、為用戶添加附加組統統可以不要了,只需要修正 tty 設備檔案的用戶組就可以啦,

group permission

重啟設備讓修改生效后,再運行一次 strace open,發現還是有問題:

$ 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 大法看一看:

$ 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 一下,輸出這次正常了:

$ 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下通過命令打開圖片

轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/325216.html

標籤:Linux

上一篇:如果存在或如果存在則更新更有效

下一篇:ELK收集MySQL慢日志并告警

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • CA和證書

    1、在 CentOS7 中使用 gpg 創建 RSA 非對稱密鑰對 gpg --gen-key #Centos上生成公鑰/密鑰對(存放在家目錄.gnupg/) 2、將 CentOS7 匯出的公鑰,拷貝到 CentOS8 中,在 CentOS8 中使用 CentOS7 的公鑰加密一個檔案 gpg -a ......

    uj5u.com 2020-09-10 00:09:53 more
  • Kubernetes K8S之資源控制器Job和CronJob詳解

    Kubernetes的資源控制器Job和CronJob詳解與示例 ......

    uj5u.com 2020-09-10 00:10:45 more
  • VMware下安裝CentOS

    VMware下安裝CentOS 一、軟硬體準備 1 Centos鏡像準備 1.1 CentOS鏡像下載地址 下載地址 1.2 CentOS鏡像下載程序 點擊下載地址進入如下圖的網站,選擇需要下載的版本,這里選擇的是Centos8,點擊如圖所示。 決定選擇Centos8后,選擇想要的鏡像源進行下載,此 ......

    uj5u.com 2020-09-10 00:12:10 more
  • 如何使用Grep命令查找多個字串

    如何使用Grep 命令查找多個字串 大家好,我是良許! 今天向大家介紹一個非常有用的技巧,那就是使用 grep 命令查找多個字串。 簡單介紹一下,grep 命令可以理解為是一個功能強大的命令列工具,可以用它在一個或多個輸入檔案中搜索與正則運算式相匹配的文本,然后再將每個匹配的文本用標準輸出的格式 ......

    uj5u.com 2020-09-10 00:12:28 more
  • git配置http代理

    git配置http代理 經常遇到克隆 github 慢的問題,這里記錄一下幾種配置 git 代理的方法,解決 clone github 過慢。 目錄 git配置代理 git單獨配置github代理 git配置全域代理 配置終端環境變數 git配置代理 主要使用 git config 命令 git單獨 ......

    uj5u.com 2020-09-10 00:12:33 more
  • Linux npm install 裝包時提示Error EACCES permission denied解

    npm install 裝包時提示Error EACCES permission denied解決辦法 ......

    uj5u.com 2020-09-10 00:12:53 more
  • Centos 7下安裝nginx,使用yum install nginx,提示沒有可用的軟體包

    Centos 7下安裝nginx,使用yum install nginx,提示沒有可用的軟體包。 18 (flaskApi) [root@67 flaskDemo]# yum -y install nginx 19 已加載插件:fastestmirror, langpacks 20 Loading ......

    uj5u.com 2020-09-10 00:13:13 more
  • Linux查看服務器暴力破解ssh IP

    在公網的服務器上經常遇到別人爆破你服務器的22埠,用來挖礦或者干其他嘿嘿嘿的事情~ 這種情況下正確的做法是: 修改默認ssh的22埠 使用設定密鑰登錄或者白名單ip登錄 建議服務器密碼為復雜密碼 創建普通用戶登錄服務器(root權限過大) 建立堡壘機,實作統一管理服務器 統計爆破IP [root ......

    uj5u.com 2020-09-10 00:13:17 more
  • CentOS 7系統常見快捷鍵操作方式

    Linux系統中一些常見的快捷方式,可有效提高操作效率,在某些時刻也能避免操作失誤帶來的問題。 ......

    uj5u.com 2020-09-10 00:13:31 more
  • CentOS 7作業系統目錄結構介紹

    作業系統存在著大量的資料檔案資訊,相應檔案資訊會存在于系統相應目錄中,為了更好的管理資料資訊,會將系統進行一些目錄規劃,不同目錄存放不同的資源。 ......

    uj5u.com 2020-09-10 00:13:35 more
最新发布
  • vim的常用命令

    Vim的6種基本模式 1. 普通模式在普通模式中,用的編輯器命令,比如移動游標,洗掉文本等等。這也是Vim啟動后的默認模式。這正好和許多新用戶期待的操作方式相反(大多數編輯器默認模式為插入模式)。 2. 插入模式在這個模式中,大多數按鍵都會向文本緩沖中插入文本。大多數新用戶希望文本編輯器編輯程序中一 ......

    uj5u.com 2023-04-20 08:43:21 more
  • vim的常用命令

    Vim的6種基本模式 1. 普通模式在普通模式中,用的編輯器命令,比如移動游標,洗掉文本等等。這也是Vim啟動后的默認模式。這正好和許多新用戶期待的操作方式相反(大多數編輯器默認模式為插入模式)。 2. 插入模式在這個模式中,大多數按鍵都會向文本緩沖中插入文本。大多數新用戶希望文本編輯器編輯程序中一 ......

    uj5u.com 2023-04-20 08:42:36 more
  • docker學習

    ###Docker概述 真實專案部署環境可能非常復雜,傳統發布專案一個只需要一個jar包,運行環境需要單獨部署。而通過Docker可將jar包和相關環境(如jdk,redis,Hadoop...)等打包到docker鏡像里,將鏡像發布到Docker倉庫,部署時下載發布的鏡像,直接運行發布的鏡像即可。 ......

    uj5u.com 2023-04-19 09:26:53 more
  • 設定Windows主機的瀏覽器為wls2的默認瀏覽器

    這里以Chrome為例。 1. 準備作業 wsl是可以使用Windows主機上安裝的exe程式,出于安全考慮,默認情況下改功能是無法使用。要使用的話,終端需要以管理員權限啟動。 我這里以Windows Terminal為例,介紹如何默認使用管理員權限打開終端,具體操作如下圖所示: 2. 操作 wsl ......

    uj5u.com 2023-04-19 09:25:49 more
  • docker學習

    ###Docker概述 真實專案部署環境可能非常復雜,傳統發布專案一個只需要一個jar包,運行環境需要單獨部署。而通過Docker可將jar包和相關環境(如jdk,redis,Hadoop...)等打包到docker鏡像里,將鏡像發布到Docker倉庫,部署時下載發布的鏡像,直接運行發布的鏡像即可。 ......

    uj5u.com 2023-04-19 09:19:04 more
  • Linux學習筆記

    IP地址和主機名 IP地址 ifconfig可以用來查詢本機的IP地址,如果不能使用,可以通過install net-tools安裝。 Centos系統下ens33表示主網卡;inet后表示IP地址;lo表示本地回環網卡; 127.0.0.1表示代指本機;0.0.0.0可以用于代指本機,同時在放行設 ......

    uj5u.com 2023-04-18 06:52:01 more
  • 解決linux系統的kdump服務無法啟動的問題

    問題:專案麒麟系統服務器的kdump服務無法啟動,沒有相關日志無法定位問題。 1、查看服務狀態是關閉的,重啟系統也無法啟動 systemctl status kdump 2、修改grub引數,修改“crashkernel”為“512M(有的機器數值太大太小都會導致報錯,建議從128M開始試,或者加個 ......

    uj5u.com 2023-04-12 09:59:50 more
  • 解決linux系統的kdump服務無法啟動的問題

    問題:專案麒麟系統服務器的kdump服務無法啟動,沒有相關日志無法定位問題。 1、查看服務狀態是關閉的,重啟系統也無法啟動 systemctl status kdump 2、修改grub引數,修改“crashkernel”為“512M(有的機器數值太大太小都會導致報錯,建議從128M開始試,或者加個 ......

    uj5u.com 2023-04-12 09:59:01 more
  • 你是不是暴露了?

    作者:袁首京 原創文章,轉載時請保留此宣告,并給出原文連接。 如果您是計算機相關從業人員,那么應該經歷不止一次網路安全專項檢查了,你肯定是收到過資訊系統技術檢測報告,要求你加強風險監測,確保你提供的系統服務堅實可靠了。 沒檢測到問題還好,檢測到問題的話,有些處理起來還是挺麻煩的,尤其是線上正在運行的 ......

    uj5u.com 2023-04-05 16:52:56 more
  • 細節拉滿,80 張圖帶你一步一步推演 slab 記憶體池的設計與實作

    1. 前文回顧 在之前的幾篇記憶體管理系列文章中,筆者帶大家從宏觀角度完整地梳理了一遍 Linux 記憶體分配的整個鏈路,本文的主題依然是記憶體分配,這一次我們會從微觀的角度來探秘一下 Linux 內核中用于零散小記憶體塊分配的記憶體池 —— slab 分配器。 在本小節中,筆者還是按照以往的風格先帶大家簡單 ......

    uj5u.com 2023-04-05 16:44:11 more