實驗環境:Ubuntu18.04 遠程伺服器 + WSL2 本機
功能需求#
最終成果#
在實現上述功能的基礎上,還添加了【即時股票數據、上次登錄時間、本月共使用時間】,有一定的容錯性【Shell 判斷、API 調用失敗返回默認值】,還有一些可嘗試功能,見文末【歷史上的今天、拒絕的拜訪者、上次登錄輸入的命令統計、在終端顯示圖片】
- em.. 今天似乎不是好日子,股市綠了:)
——> 下面時間扭轉 <——
實現過程#
【首先瞅瞅連接主機的默認消息】
- 這些消息我都不要,一切重頭,做一個完全自主 [到處拼湊] 的消息提醒
原開機信息去除#
如何去除上面這些信息呢?
- 經高人 [宿船長] 指點,“到 /etc/update-motd.d 裡去找找”,vim update-motd.d 顯示如下:
- 原本以為是個文件... 進去點開每個文件可以對應到上面的登錄信息
- 這裡 motd 的意思是 message of the day—— 每日消息
- 它可以是每次登錄都更新一次的;也可以是事先存好不變的
- 可參考 man 5 update-motd,這裡參考MOTD 是什麼?-cnblogs
- 裡面提到:是由一個叫 pam 的服務下的 login 模塊管理著 MOTD 的輸出,sudo vim /etc/pam.d/login,註釋掉與 motd 相關的功能後,但是並不生效
- 原來 /etc/pam.d/login 是用來控制本機登錄的,而我使用 SSH 登錄,有另一個配置文件 /etc/pam.d/sshd
- 參考Disable everything in update-motd.d dir in ubuntu server-StackExchange
- 我要禁用通過 SSH 連接後的登錄提示消息,所以 sudo vim /etc/pam.d/sshd 進入
- 對 motd 相關功能進行註釋
- 我要禁用的是 update-motd.d 裡的顯示消息,屬於動態信息,所以註釋第 33 行即可
- 而靜態消息的來源 /etc/motd 在主機上不存在,可以不管
【重連主機,清爽許多】
- 但還有一個 Last login 信息
- 它屬於 sshd 所控制,找到 sshd 的配置文件
- sudo vim /etc/ssh/sshd_config,將 PrintLastLog 設置為 no
- 再重啟 sshd 服務使其生效,sudo service sshd restart [似曾相識]
【至此,回到了解放前】
前期準備#
找到開機運行的文件#
【使用 zsh 開機配置文件】
Shell:zsh
- 通過 man zsh 搜索 FILES,查看 zsh 的開機配置文件,有很多
- 根據語境,使用.zlogin 配置
- 在家目錄下創建.zlogin,vim ~/.zlogin
最近登錄次數 [本月]#
【本月登錄:40 次】
【通過 last 獲取】
- 當前用戶
- 通過截取 who am i 的第一個元素:who am i | cut -d " " -f 1
- 通過獲取 USER 環境變量:env | grep USER | cut -d "=" -f 2
- last 獲取登錄信息→查找當前用戶的登錄信息並計數
last | grep -c `env | grep USER | cut -d "=" -f 2`
[PS] 顯示更多的信息需找到:
- /var/log/wtmp.x,x ∈ [0-9]
- 參考How to read older login info using the “last” command?——StackExchange
上次停留時間 [本月]#
【上次停留:01 小時 03 分】
【通過 last 獲取】
- last 獲取登錄信息→找到該用戶的登錄信息→匹配 “()” 式樣的連接時間的行→獲取最近一次的→按照 “ ( ”、“ ) ” 切割得到上次停留時間,
- 時間格式為小時:分鐘
- 參考AWK - 正則表達式—— 簡單教程
last | grep `env | grep USER | cut -d "=" -f 2` | awk '/\(*\)/' | head -1 | cut -d "(" -f 2 | cut -d ")" -f 1
尋找名人名言接口#
【名人名言顯示】
【來源:名人名言——Free API】
- 每天最多申請 100 次
- 通過 curl 請求:curl https://v1.alapi.cn/api/mingyan
- 返回格式:json
- 可選參數:typeid [1~45]
- 隨機獲得的 json 數據如下:
【使用jq處理 json 數據】
- 使用 sudo apt install jq 安裝
- 使用如下命令
curl -s https://v1.alapi.cn/api/mingyan | jq '.data | [.content, .author]' | jq 'join("————")'
- 參考jq tutorial(簡單使用)、jq manual(細節操作)
- 另參考使用 Shell 腳本來處理 JSON—— 博客
- 雖然可以使用 awk、sed 命令去針對不同的 json 數據做處理,但這裡使用強大的 jq 有更強的魯棒性
尋找當地當日天氣預報接口#
【天氣顯示】
【來源:wttr.in——Github】
- 可一行輸出,更簡潔
- 自定義參數如下:
- 主要顯示位置、天氣圖標、體感溫度以及晚上的月亮形狀,調用如下命令
curl wttr.in/\?format="%l:+%c+%t+feels+like+%f,+moon+tonight:+%m\n"
設置溫馨問候#
【問候,隨機顏色】
- 可通過 sudo apt install figlet 安裝
- [擴充字體庫]figlet-fonts——Github,git clone 後,把所有文件放到 /usr/share/figlet/ 裡
- 通過 showfigfonts "Hey Double" 可以查看關於 Hey Double 所有字體演示
- figlet 的可選項很多,如下:
- 自行搭配後選擇自己喜歡的樣式,我的搭配:figlet -t -r Hey Double -f miniwi
- 再使用 lolcat 給問候上色:通過 sudo apt install lolcat 即可安裝
- 使用如下命令
figlet Hey Double -f miniwi | lolcat
figlet -t -r You\'re back -f miniwi | lolcat
腳本製作 [含顏色優化]⭐#
~/.login.sh#
- 【關鍵】在於 jq、awk、sed 的使用
- 如果 curl 返回不是預期的,做一些保護機制
- 對於一些邊界,以及數組、變量的操作,日後再多加琢磨
- ⭐注意 zsh、bash 的兼容性
- zsh 下:數組索引從 1 開始,特殊符號一定要轉義❗
- [PS]
- 額外添加的功能【即時股票數據、上次登錄時間、本月共使用時間】見文末 —— 附加部分
- 股票數據的 appkey 和 sign 需要去官網生成自己的
.zlogin#
- ⭐不使用 source 調用腳本,而是根據 Shell 類型使用 zsh/bash [默認 bash],因為
- 這個開機腳本只是用來顯示,不需要添加環境變量
- 使用 zsh/bash 會開一個子 Shell 運行腳本,而使用 source 是在當前 Shell 運行,腳本裡添加的變量會在環境中生效 [可通過 set 查看所有本地定義的環境變量]
【探討】source 和 bash 調用腳本的區別#
- bash 和 source 腳本的結果不一致,前面測試都是用的 bash,而開機腳本是使用 source 執行的,會調用當前 Shell——zsh 執行
- 開機顯示如下
- 使用 set -x 打開腳本調試,可以看到完整過程
- 左邊是代碼,右邊是調試結果
- 可以看到 index 變量變成空的了!
- 【①】原來就是 zsh 和 bash 中,傳說中的【數組起始索引】不一致的問題
- 於是考慮對運行腳本的 shell 做一個判斷
- 使用 ${SHELL} 判斷並不有效,在 zsh 裡不管用 source 還是 bash 都指向 /usr/bin/zsh
- 但有另一種檢測方法
- 參考How to get shell to self-detect using zsh or bash——Stackoverflow
- 【或】可借鑒下文方法,調用數組元素的奇門絕技?未嘗試,上述方法可行🆗
- 【②】數組下標問題解決了,還要注意 zsh 的其它兼容性問題
- ❗ 特殊符號,這裡 jq 後面的 [] 需要使用轉義符 \
【參考】
- Shell 命令替換:將命令的輸出結果賦值給變量——C 語言中文網
- $() 支持嵌套,反引號不行
- $() 僅在 Bash 中有效,而反引號可在多種 Shell 中使用
- Shell 中實現字符串切割的幾種方法——CSDN
- ⭐arr=(${parameter//pattern/string})
- echo args | tr "oldSpilt" "newSpilt"
- awk 入門教程—— 阮一峰
- awk 格式化打印—— 易百教程
- Shell source 命令:使環境變量配置文件強制生效——C 語言中文網
附加#
全球股票指數#
curl http://api.k780.com/\?app=finance.globalindex\&inxids=1010,1011,1013\&appkey=你的key\&sign=你的sign | jq .
上一次登錄時間#
- last
last | grep `env | grep USER | cut -d "=" -f 2` | awk '/\(*\)/' | head -1 | awk '{printf "%s %s %s —— %s", $4, $5, $6, $7}'
- 有待改進,切割方式較死板
本月共使用的時間#
ac | awk '{print int($NF)}'
- ac 命令:顯示用戶的連接時間數據
- ac 該用戶本月共使用的時間
- ac -d 該用戶本月每天的連接時間
- 參考ac 命令詳解——commandnotfound
—— 可嘗試 ——#
歷史上的今天#
curl http://api.juheapi.com/japi/toh\?key=你的key\&v=1.0\&month=11\&day=1
- 統計有多少條記錄
curl -s http://api.juheapi.com/japi/toh\?key=你的key\&v=1.0\&month=1\&day=1 | jq '.result | length'
- 隨機輸出其中一條
- 生成 0~N 的隨機數
$(( ${RANDOM} % ${N} ))
拒絕了多少位拜訪者#
- 從上次登錄到現在,有多少次失敗登錄記錄
sudo lastb
- 需要 sudo 權限,只想到在腳本裡放密碼,不安全
上次登錄輸入的命令統計#
【通過 history 統計】
- 輸入了多少條命令
- 哪個命令是你的最愛
- 經常輸入錯誤的命令
目測比較耗時
參考資料#
- 在終端顯示圖片,可參考termpix——Github
- curl 的用法指南—— 阮一峰
- Free API 接口大全
- NowAPI
- 在 Linux 字符界面中獲取天氣預報—— 知乎
- Is there a reason why the first element of a Zsh array is indexed by 1 instead of 0?——StackExchange
- Bash 裡的數組下標從 0 開始,而 zsh 從 1 開始
- 在 Linux 中配置 SSH 登錄導語 [靜態信息:Banner、motd]—— 博客