主頁 > 後端開發 > Linux 命令 su 和 sudo 的區別?

Linux 命令 su 和 sudo 的區別?

2021-09-30 06:20:51 後端開發

來源:Jun Tao

地址:https://tanjuntao.github.io/

之前一直對 susudo 這兩個命令犯迷糊,最近專門搜了這方面的資料,總算是把兩者的關系以及用法搞清楚了,這篇文章來系統總結一下,

1. 準備作業

因為本篇博客中涉及到用戶切換,所以我需要提前準備好幾個測驗用戶,方便后續切換,

Linux 中新建用戶的命令是 useradd ,一般系統中這個命令對應的路徑都在 PATH 環境變數里,如果直接輸入 useradd 不管用的話,就用絕對路徑名的方式:/usr/sbin/useradd

useradd 新建用戶命令只有 root 用戶才能執行,我們先從普通用戶 ubuntu 切換到 root 用戶(如何切換后文會介紹):

ubuntu@VM-0-14-ubuntu:~$ su -
Password:                                         # 輸入 root 用戶登錄密碼
root@VM-0-14-ubuntu:~# useradd -m test_user       # 帶上 -m 引數
root@VM-0-14-ubuntu:~# ls /home
test_user  ubuntu                                 # 可以看到 /home 目錄下面有兩個用戶了

因為還沒有給新建的用戶 test_user 設定登錄密碼,這就導致我們無法從普通用戶 ubuntu 切換到 test_user,所以接下來,我們需要用 root 來設定 test_user 的登錄密碼,需要用到 passwd 命令:

root@VM-0-14-ubuntu:~# passwd test_user
Enter new UNIX password:                          # 輸出 test_user 的密碼
Retype new UNIX password:       
passwd: password updated successfully
root@VM-0-14-ubuntu:~#

接著我們輸入 exit 退出 root 用戶到 普通用戶 ubuntu:

root@VM-0-14-ubuntu:~# exit
logout
ubuntu@VM-0-14-ubuntu:~$

可以看到,命令提示符前面已經由 root 變成 ubuntu,說明我們現在的身份是 ubuntu 用戶,

2. su 命令介紹及主要用法

首先需要解釋下 su 代表什么意思,

之前一直以為 susuper user,查閱資料之后才知道原來表示 switch user

知道 su 是由什么縮寫來的之后,那么它提供的功能就顯而易見了,就是切換用戶

2.1 - 引數

su 的一般使用方法是:

su  <user_name>

或者

su - <user_name>

兩種方法只差了一個字符 -,會有比較大的差異:

  • 如果加入了 - 引數,那么是一種 login-shell 的方式,意思是說切換到另一個用戶 <user_name> 之后,當前的 shell 會加載 <user_name> 對應的環境變數和各種設定;
  • 如果沒有加入 - 引數,那么是一種 non-login-shell 的方式,意思是說我現在切換到了 <user_name>,但是當前的 shell 還是加載切換之前的那個用戶的環境變數以及各種設定,

光解釋會比較抽象,我們看一個例子就比較容易理解了,

我們首先從 ubuntu 用戶以 non-login-shell 的方式切換到 root 用戶,比較兩種用戶狀態下環境變數中 PWD 的值(su 命令不跟任何 <user_name> ,默認切換到 root 用戶):

ubuntu@VM-0-14-ubuntu:~$ env | grep ubuntu
USER=ubuntu
PWD=/home/ubuntu                                         # 是 /home/ubuntu
HOME=/home/ubuntu
# 省略......
ubuntu@VM-0-14-ubuntu:~$ su                              # non-login-shell 方式
Password:                                                # 輸入 root 用戶登錄密碼
root@VM-0-14-ubuntu:/home/ubuntu# env | grep ubuntu
PWD=/home/ubuntu                                         # 可以發現還是 /home/ubuntu
root@VM-0-14-ubuntu:/home/ubuntu#

我們的確是切換到 root 用戶了,但是 shell 環境中的變數并沒有改變,還是用之前 ubuntu 用戶的環境變數,

接著我們從 ubuntu 用戶以 login-shell 的方式切換到 root 用戶,同樣比較兩種用戶轉臺下環境變數中 PWD 的值:

ubuntu@VM-0-14-ubuntu:~$ env | grep ubuntu
USER=ubuntu
PWD=/home/ubuntu                               # 是 /home/ubuntu
HOME=/home/ubuntu
# 省略.......
ubuntu@VM-0-14-ubuntu:~$ su -                  # 是 login-shell 方式
Password:
root@VM-0-14-ubuntu:~# env | grep root
USER=root
PWD=/root                                      # 已經變成 /root 了
HOME=/root
MAIL=/var/mail/root
LOGNAME=root
root@VM-0-14-ubuntu:~#

可以看到用 login-shell 的方式切換用戶的話,shell 中的環境變數也跟著改變了,

總結:具體使用哪種方式切換用戶看個人需求:

  • 如果不想因為切換到另一個用戶導致自己在當前用戶下的設定不可用,那么用 non-login-shell 的方式;
  • 如果切換用戶后,需要用到該用戶的各種環境變數(不同用戶的環境變數設定一般是不同的),那么使用 login-shell 的方式,

2.2 切換到指定用戶

前面已經介紹了,如果 su 命令后面不跟任何 <user_name>,那么默認是切換到 root 用戶:

ubuntu@VM-0-14-ubuntu:~$ su -
Password:                                       # root 用戶的密碼
root@VM-0-14-ubuntu:/home/ubuntu#

因為我們在 1. 準備作業 部分已經新建了一個 test_user 用戶,并且我們也知道 test_user 用戶的登錄密碼(root 用戶設定的),我們就能從 ubuntu 用戶切換到 test_user 用戶:

ubuntu@VM-0-14-ubuntu:~$ su - test_user
Password:                                       # test_user 用戶的密碼
$

2.3 -c 引數

前面的方法中,我們都是先切換到另一個用戶(root 或者 test_user),在哪個用戶的狀態下執行命令,最后輸入 exit 回傳當前 ubuntu 用戶,

還有一種方式是:不需要先切換用戶再執行命令,可以直接在當前用戶下,以另一個用戶的方式執行命令,執行結束后就回傳當前用戶,這就得用到 -c 引數,

具體使用方法是:

su - -c "指令串"                                  # 以 root 的方式執行 "指令串"

我么看個例子:

ubuntu@VM-0-14-ubuntu:~$ cat /etc/shadow
cat: /etc/shadow: Permission denied                # ubuntu 用戶不能直接查看 /etc/shadow 檔案內容

ubuntu@VM-0-14-ubuntu:~$ su - -c "tail -n 4 /etc/shadow"
Password:                                          # 輸入 root 用戶密碼
ubuntu:$1$fZKcWEDI$uwZ64uFvVbwpHTbCSgim0/:18352:0:99999:7:::
ntp:*:17752:0:99999:7:::
mysql:!:18376:0:99999:7:::
test_user:$6$.ZY1lj4m$ii0x9CG8h.JHlh6zKbfBXRuolJmIDBHAd5eqhvW7lbUQXTRS//89jcuTzRilKqRkP8YbYW4VPxmTVHWRLYNGS/:18406:0:99999:7:::
ubuntu@VM-0-14-ubuntu:~$                            # 執行完馬上回傳 ubuntu 用戶而不是 root 用戶

這種執行方式和后面要介紹的 sudo 很像,都是臨時申請一下 root 用戶的權限,但還是有差異,我們接著往后看,

3. sudo 命令介紹及主要用法

首先還是解釋下 sudo 命令是什么意思,

sudo 的英文全稱是 super user do,即以超級用戶(root 用戶)的方式執行命令,這里的 sudo 和之前 su 表示的 switch user 是不同的,這點需要注意,很容易搞混,

我們先介紹 sudo 命令能做什么事情,然后說明為何能做到這些,以及如何做到這些,

我們開始,

3.1 主要用法

我們在 Linux 中經常會碰到 Permission denied 這種情況,比如以 ubuntu 用戶的身份查看 /etc/shadow 的內容,因為這個檔案的內容是只有 root 用戶能查看的,

那如果我們想要查看怎么辦呢?這時候就可以使用 sudo :

ubuntu@VM-0-14-ubuntu:~$ tail -n 3 /etc/shadow
tail: cannot open '/etc/shadow' for reading: Permission denied      # 沒有權限
ubuntu@VM-0-14-ubuntu:~$ sudo !!                                    # 跟兩個驚嘆號
sudo tail -n 3 /etc/shadow
ntp:*:17752:0:99999:7:::
mysql:!:18376:0:99999:7:::
test_user:$6$.ZY1lj4m$ii0x9CG8h.JHlh6zKbfBXRuolJmIDBHAd5eqhvW7lbUQXTRS//89jcuTzRilKqRkP8YbYW4VPxmTVHWRLYNGS/:18406:0:99999:7:::
ubuntu@VM-0-14-ubuntu:~$

實體中,我們使用了 sudo !! 這個小技巧,表示重復上面輸入的命令,只不過在命令最前面加上 sudo

因為我已經設定了 sudo 命令不需要輸入密碼,所以這里 sudo !! 就能直接輸出內容,如果沒有設定的話,需要輸入當前這個用戶的密碼,例如本例中,我就應該輸入 ubuntu 用戶的登錄密碼,

兩次相鄰的 sudo 操作,如果間隔在 5min 之內,第二次輸入 sudo 不需要重新輸入密碼;如果超過 5min,那么再輸入 sudo 時,又需要輸入密碼,所以一個比較省事的方法是設定 sudo 操作不需要密碼,后面介紹如何設定,

sudo 除了以 root 用戶的權限執行命令外,還有其它幾個用法,這里做簡單介紹,

切換到 root 用戶:

sudo su -

這種方式也能以 login-shell 的方式切換到 root 用戶,但是它和 su - 方法是由區別的:

  • 前者輸入 sudo su - 后,需要提供當前用戶的登錄密碼,也就是 ubuntu 用戶的密碼;
  • 后者輸入 su - 后,需要提供 root 用戶的登錄密碼,

還有一個命令:

sudo -i

這個命令和 sudo su - 效果一致,也是切換到 root 用戶,也是需要提供當前用戶(ubuntu 用戶)的登錄密碼,

我們現在切換到 test_user 用戶,嘗試顯示 /etc/shadow 檔案的內容:

ubuntu@VM-0-14-ubuntu:~$ su - test_user
Password:                                       # test_user 的密碼
$ sudo cat /etc/shadow
[sudo] password for test_user:                  # test_user 的密碼
test_user is not in the sudoers file.  This incident will be reported.
$

我們會看到倒數第二行中的錯誤提示資訊,我們無法查看 /etc/shadow 的內容,這是為什么?為什么 ubuntu 可以使用 sudo 但是 test_user 不行呢?

這就涉及到 sudo 的作業原理了,

3.2 sudo 作業原理

一個用戶能否使用 sudo 命令,取決于 /etc/sudoers 檔案的設定,

從 3.1 節中我們已經看到,ubuntu 用戶可以正常使用 sudo ,但是 test_user 用戶卻無法使用,這是因為 /etc/sudoers 檔案里沒有配置 test_user,

/etc/sudoers 也是一個文本檔案,但是因其有特定的語法,我們不要直接用 vim 或者 vi 來編輯它,需要用 visudo 這個命令,輸入這個命令之后就能直接編輯 /etc/sudoers 這個檔案了,

需要說明的是,只有 root 用戶有權限使用 visudo 命令,

我們先來看下輸入 visudo 命令后顯示的內容,

輸入(root 用戶):

root@VM-0-14-ubuntu:~# visudo

輸出:

# User privilege specification
root    ALL=(ALL:ALL) ALL

# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL

# See sudoers(5) for more information on "#include" directives:

#includedir /etc/sudoers.d
ubuntu  ALL=(ALL:ALL) NOPASSWD: ALL

解釋下每一行的格式:

  • 第一個表示用戶名,如 rootubuntu 等;
  • 接下來等號左邊的 ALL 表示允許從任何主機登錄當前的用戶賬戶;
  • 等號右邊的 ALL 表示:這一行行首對一個的用戶可以切換到系統中任何一個其它用戶;
  • 行尾的 ALL 表示:當前行首的用戶,能以 root 用戶的身份下達什么命令,ALL 表示可以下達任何命令,

我們還注意到 ubuntu 對應的那一行有個 NOPASSWD 關鍵字,這就是表明 ubuntu 這個用戶在請求 sudo 時不需要輸入密碼,到這里就解釋了前面的問題,

同時我們注意到,這個檔案里并沒有 test_user 對應的行,這也就解釋了為什么 test_user 無法使用 sudo 命令,

接下來,我們嘗試將 test_user 添加到 /etc/sudoers 檔案中,使 test_user 也能使用 sudo 命令,我們在最后一行添加:

test_user  ALL=(ALL:ALL)  ALL       # test_user 使用 sudo 需要提供 test_user 的密碼

接下來我們再在 test_user 賬戶下執行 sudo

ubuntu@VM-0-14-ubuntu:~$ su - test_user
Password:
$ tail -n 3 /etc/shadow
tail: cannot open '/etc/shadow' for reading: Permission denied
$ sudo tail -n 3 /etc/shadow                   # 加上 sudo
ntp:*:17752:0:99999:7:::
mysql:!:18376:0:99999:7:::
test_user:$6$.ZY1lj4m$ii0x9CG8h.JHlh6zKbfBXRuolJmIDBHAd5eqhvW7lbUQXTRS//89jcuTzRilKqRkP8YbYW4VPxmTVHWRLYNGS/:18406:0:99999:7:::
$

可以看到,現在已經可以使用 sudo 了,

3.3 思考

我們已經看到了,如果一個用戶在 /etc/sudoers 檔案中,那么它就具有 sudo 權限,就能通過 sudo su - 或者 sudo -i 等命令切換到 root 用戶了,那這時這個用戶就變成 root 用戶了,那這不對系統造成很大的威脅嗎?

實際上的確是這樣的,所以如果在編輯 /etc/sudoers 檔案賦予某種用戶 sudo 權限時,必須要確定該用戶是可信任的,不會對系統造成惡意破壞,否則將所有 root 權限都賦予該用戶將會有非常大的危險,

當然,root 用戶也可以編輯 /etc/sudoers 使用戶只具備一部分權限,即只能執行一小部分命令,有興趣的讀者可以參考 Reference 部分第二條,這篇文章不再贅述,

4. 二者的差異對比

我們已經看到:

  • 使用 su - ,提供 root 賬戶的密碼,可以切換到 root 用戶;
  • 使用 sudo su - ,提供當前用戶的密碼,也可以切換到 root 用戶

兩種方式的差異也顯而易見:如果我們的 Linux 系統有很多用戶需要使用的話,前者要求所有用戶都知道 root 用戶的密碼,這顯然是非常危險的;后者是不需要暴露 root 賬戶密碼的,用戶只需要輸入自己的賬戶密碼就可以,而且哪些用戶可以切換到 root,這完全是受 root 控制的(root 通過設定 /etc/sudoers 實作的),這樣系統就安全很多了,

一般都是推薦使用 sudo 方式,

References

  • https://www.rootusers.com/the-difference-between-su-and-sudo-commands-in-linux/
  • 《鳥哥的 Linux 私房菜》13.4 節:使用者身份切換
  • https://github.com/ustclug/Linux101-docs/blob/master/docs/Ch05/index.md
  • https://www.maketecheasier.com/differences-between-su-sudo-su-sudo-s-sudo-i/
  • https://stackoverflow.com/questions/35999671/whats-the-difference-between-sudo-i-and-sudo-su?r=SearchResults
  • https://www.zhihu.com/question/51746286
  • https://www.linuxidc.com/Linux/2017-06/144916.htm

近期熱文推薦:

1.1,000+ 道 Java面試題及答案整理(2021最新版)

2.別在再滿屏的 if/ else 了,試試策略模式,真香!!

3.臥槽!Java 中的 xx ≠ null 是什么新語法?

4.Spring Boot 2.5 重磅發布,黑暗模式太炸了!

5.《Java開發手冊(嵩山版)》最新發布,速速下載!

覺得不錯,別忘了隨手點贊+轉發哦!

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

標籤:其他

上一篇:Docker-Java限制cpu和記憶體及淺析原始碼解決docker磁盤掛載失效問題

下一篇:python超贊插件you-get,執行一行命令即可下載、命令列下載工具推薦!

標籤雲
其他(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)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more