实验环境: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]—— 博客