Linux老手也常踩的5个Unix环境搭建坑
|
去年国庆节,我蹲在机房三号柜后面啃冷掉的牛肉馅饼,总编站我斜后方三步远,拿激光笔点投影幕布上一行“/etc/passwd 权限检查脚本”,说这稿子“不够痛”。我嚼着饼渣回他:“你让我写‘老手也常踩的坑’,又不让提真实操作现场——那不就是写《如何用 ssh 登录自己》?”他手机响了一声,没接,但拇指在屏上划了三下,应该是微信撤回。我没动桌上那支蓝墨水漏了半管的派克,它从七月就立那儿,笔帽歪着。 先扔结论:这五个坑根本不是技术缺陷,是 Unix 环境自己筛人的筛子。优胜劣汰?不,是优胜劣汰得特别不讲理——筛掉的不是菜鸟,是那些还信“配完就跑”的人。我原以为第七次重装 CentOS 7 就能绕过 /usr/local/bin 和 /usr/bin 的 PATH 鬼打墙,结果 root 用户里 PATH 居然比普通用户少俩路径,而且还是因为 cron 服务用的 shell 是 dash 不是 bash。这个我敢打包票,我截图存了十七个终端历史,光 grep -v "bash" 就敲了四遍。 第一个坑:时区改了,systemd-logind 却还在用 UTC 跟 session 作对。不是 timeadj 问题,是 logind.conf 里一句 `#NAutoVTs=6` 没被注释,而你压根没看见它下面三行空格后藏着的 `#TTYPath=/dev/tty` ——但偏偏只有这一行生效了。我查了十九分钟 journalctl -u systemd-logind,直到发现 /var/log/wtmp 里凌晨两点登录记录全是 GMT+0 时间戳。隔壁桌实习生端着咖啡转身时洒了一半在键盘上,她没擦,直接按了 Ctrl+Alt+F2 切 tty,咖啡顺着 esc 键缝往下滴,滴了十八秒。我盯着那滴咖啡,忽然想起上个月帮财务部同事重装 Ubuntu,他非要自己改 /etc/default/rcS 里的 TZ,改完 sudo reboot 不起作用,最后发现是他在 /etc/timezone 文件里写了 Asia/Shanghai,但在 /etc/localtime 里 ln -sf 指向了 /usr/share/zoneinfo/Asia/Chongqing。两个城市时区相同,符号链接指向不同路径,logind 认一个、systemd-timedated 读另一个。我说不准哪个组件优先级高,反正我删了 Chongqing 那个软链,reboot 后登进去看 `date`,它笑了。我也没笑。 第二个坑:SELinux 的 restorecon 在 /home 下狂奔三分钟才吐出“Not a directory”警告,因为你前夜手滑把 /home/john/.ssh/config 改成了 755。这不是权限错了,是 context 标签卡在 type=file,而 sshd 偏偏要检查 type=ssh_home_t,但它不报错,只默默拒绝 PubKey 认证,连 auth.log 都干干净净。我试到第四台机器才发现,是在 /etc/selinux/targeted/contexts/files/file_contexts.homedirs 里少了一句 `/home(/.)? system_u:object_r:home_root_t:s0` ——等等,不对,其实那一行有,是我 grep 的时候用了 `-i` 忘了大小写,文件里是 `/home(/.)? system_u:object_r:home_root_t:s0`,但我抄的时候抄成 home_root_t:s0,漏了前面的 system_u:object_r:。这事儿我就不说了,反正现在我改 config 都要开三个终端窗:一个 watch -n1 'ls -Z /home/john/.ssh',一个 tail -f /var/log/audit/audit.log | aureport -f -i,第三个……第三个在跑 ansible,ansible 脚本里我把 copy 模块写成 content,忘了 template,结果 /etc/ssh/sshd_config 被写成纯字符串,连变量都没展开。主编说那期选题毙掉之前,小编已经改了三百七十二稿,最后一版标题叫《Unix环境搭建:你以为的常识正在杀死你的上线节奏》,我扫了眼文档右下角作者栏写的“技术审核:XXX”,名字后头打了星号,鼠标悬停显示“已离职(8.17)”。 第三个坑:udev 规则里写 `SUBSYSTEM=="usb", ATTR{idVendor}=="046d", SYMLINK+="webcam_logitech"`,设备插上之后 `/dev/webcam_logitech` 生成了,可 opencv 读不到——因为内核 5.15 开始默认禁用了 usbfs,而 opencv 2.x 用的是 /proc/bus/usb,不是 /dev。你搜了一下午 stackoverflow,答案全是“升级 opencv”,没人告诉你该 `echo 'options usbcore old_style_usbfs=1' > /etc/modprobe.d/usbfs.conf`,再 `dracut -f`。我试到第九次 reboot 才想起翻 initrd,打开看到 modules.list 里根本没有 usbcore.ko。这时候主编微信弹出来问“今天能不能交终稿”,我回了个“…”。他回了个“。”。然后我就去拆了台旧 ThinkPad 的 USB 接口焊点拍照,图发群里,说“各位,这是真正的 udev 上古协议接口实物图”,没人接话。后来我知道,那个接口焊点其实是 HDMI 的,我拍反了。但图没撤回。
文章配图,仅供参考 第四个坑:sudoers 里写 `%wheel ALL=(ALL) NOPASSWD: /bin/systemctl restart nginx`,看着没问题,结果 Jenkins pipeline 里执行失败。不是路径问题,是 sudo 默认关闭了环境变量继承,而 nginx 的 systemd service 文件里写了 `EnvironmentFile=/etc/sysconfig/nginx`,里面有个 `NGINX_CONF_PATH=/etc/nginx/nginx.conf`,但 sudo 不带 -E 就不加载它。我在 Jenkins 控制台里手动补了 -E,成功了;再加到 pipeline 里,又失败——因为 Jenkins agent 启动时用的是 jenkins 用户的 ~/.bashrc,里头有一行 `unset SUDO_UID`,导致 sudo 降权失败。这事我没细查,反正我最后把整个 service 改成 ExecStartPre=/bin/sh -c 'source /etc/sysconfig/nginx && echo "$NGINX_CONF_PATH"',绕过去了。我原以为绕过去就完了,结果客户生产环境跑一周后反馈 502 错误,查下来是 SELinux 把 ExecStartPre 的 /bin/sh 标记为 bin_t,而不是 unconfined_exec_t,所以 denied { execute }。我说不准这标签到底是 policycoreutils-minimal 没装全,还是 semodule -l | grep nginx 没启用模块,反正我没再碰。 第五个坑?呵,第五个根本不是坑,是编辑部新来的总编说“读者要实操路径”,非让我加个“一键检测脚本”。我写了个 bash,跑完输出五条 yes/no。他看了说“太干”,让我加个“温馨提醒:请确保您拥有 root 权限哦~”。我盯着那波浪线,想起上季度 KPI 里“内容互动率”占比涨了12%,但服务器巡检工单量掉了37%。工资条上“技能补贴”那栏,三年没动过数字。我关掉终端,把脚本里所有 echo 换成 printf "%-30s %s\ (编辑:站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |


Linux无障碍环境搭建:CSS工程师的语音导航实战指南
Windows数据科学环境搭建:5年运维避坑实战
Linux数据库环境搭建七步实操指南
Unix调试总卡壳?5个隐性陷阱90%人中招
Linux安全环境搭建:15年性能工程师实战指南
嵌入式Linux开发者Unix环境搭建避坑指南
Windows环境搭建的3大安全断点:90%运维人忽视