一、变量到底是什么

原笔记把变量解释得很朴素:变量就是会变化的值,在脚本里本质上可以理解为“变量名指向内存中的一块空间”。

最基础的创建和取值方式如下:

oldboy=lidao996
echo $oldboy

取值时既可以写成 $day,也可以写成 ${day}。当变量名后面还要拼接其他字符时,推荐使用花括号:

day=6
echo ${day}hao

二、变量命名规则要先立住

原笔记给出的命名规则非常实用:

1、不能以数字开头。 2、不能以特殊符号开头,但可以用下划线开头。 3、推荐用字母开头。

命名风格上,Shell 脚本更推荐现代式写法:

  • person_of_name
  • user_home_dir
  • backup_target_dir

尽量不要写成 a1a2 这种无法表达含义的名字,否则脚本一长就很难维护。

三、Shell 变量分哪几类

原笔记把变量分成三类:

  • 普通变量:脚本里最常见的局部变量,例如 name=oldboy
  • 环境变量:系统层面可继承的变量,例如 PATHLANG
  • 特殊变量:Shell 专门提供的变量,例如 $1$#$?

这一篇先把普通变量和环境变量讲透,特殊变量放到下一篇单独整理。

四、普通变量如何使用

普通变量最常见的写法就是直接赋值:

day=6
echo $day
echo ${day}

这种变量一般在当前 Shell 或当前脚本内部有效,最适合做:

  • 中间结果保存
  • 命令结果缓存
  • 配置参数统一管理

五、环境变量和 envexportdeclare

环境变量的特点是“一处定义,处处可见”,尤其适合让子 Shell 也能继承变量值。

原笔记列出的几个相关命令分别用于:

  • env:查看当前环境变量
  • export:把变量导出为环境变量
  • declare:声明变量及其属性

例如:

env | grep LANG
export LANG=zh_CN.UTF-8
declare site_name=oldboy

六、运维最常碰到的环境变量有哪些

原笔记列出了很多常见变量,下面这些是最值得直接记住的。

6.1 路径与语言相关

  • PATH:命令查找路径,新装软件后经常要补 PATH。
  • LANG:系统语言和字符集,例如 zh_CN.UTF-8
  • PS1:命令提示符格式。
  • HOSTNAME:主机名。
  • UIDEUID:当前用户 ID,经常用于判断是否为 root。

6.2 历史命令相关

生产环境安全优化里经常会碰到下面这组变量:

  • HISTSIZE
  • HISTFILESIZE
  • HISTCONTROL
  • HISTFILE
  • PROMPT_COMMAND

例如,PROMPT_COMMAND 就经常被用来做行为审计;HISTCONTROL=ignorespace 可以让前面带空格的命令不进入历史记录。

6.3 脚本处理中常见的变量

  • IFS:字段分隔符,常和循环、读文件搭配使用。
  • TMOUT:超时自动退出。

七、环境变量怎么修改才规范

临时修改直接用 export 即可:

export LANG=zh_CN.UTF-8

永久修改则通常写进 /etc/profile 或对应的用户配置文件中:

vim /etc/profile
export LANG=zh_CN.UTF-8

写完之后,可以用下面的命令验证:

env | grep LANG

八、环境变量常见生效文件有哪些

原笔记梳理了 5 个重点位置:

  • /etc/profile:全局生效,常放函数、环境变量、别名
  • /etc/bashrc:全局别名等配置
  • ~/.bashrc:当前用户自己的 Shell 配置
  • ~/.bash_profile:当前用户登录相关配置
  • /etc/profile.d/:登录时自动加载的 .sh 文件目录

其中 /etc/profile.d/ 非常适合放“登录后自动展示信息”的脚本。

九、实战:用户登录后自动显示系统信息

原笔记里的登录欢迎信息脚本很典型,适合练习变量赋值和命令替换:

#!/bin/bash
sys_hostname=$(hostname)
sys_ip_addrs=$(hostname -I)
sys_mem_total=$(free -h | awk 'NR==2{print $2}')
sys_mem_free=$(free -h | awk 'NR==2{print $NF}')
sys_load=$(uptime | awk '{print $(NF-2),$(NF-1),$NF}')

cat <<EOF
      主机名: ${sys_hostname}
      ip地址: ${sys_ip_addrs}
      总内存: ${sys_mem_total}
      可用内存: ${sys_mem_free}
      系统负载: ${sys_load}
EOF

想让它在每次登录后自动执行,可以把脚本软链接到 /etc/profile.d/

ln -s /server/scripts/devops-shell/02.sys_login_info.sh /etc/profile.d/sys_login_info.sh

十、如何判断是 SSH 登录还是本地切换用户

原笔记最后给了一个很实战的小提示:如果环境变量里存在下面两项,通常说明当前会话是通过 SSH 建立的:

SSH_CLIENT=192.168.1.108 10015 22
SSH_TTY=/dev/pts/0

这个判断经常会被用到:

  • 登录欢迎信息只给远程用户展示
  • 审计脚本区分 SSH 登录和 su 切换
  • 自动化脚本按登录方式做不同处理

十一、这一篇要掌握到什么程度

学完变量基础后,至少要做到下面几件事:

  • 能写出规范的变量名。
  • 能区分普通变量和环境变量。
  • 知道环境变量应该改在哪里。
  • 能写出一个依赖变量和命令替换的小脚本。

变量这一关过了,后面的判断、循环、函数才真正有抓手。