readonly 是 bash 内建命令,用于将变量、数组或函数标记为只读,赋值后不可修改或删除;支持 readonly name=value 一步锁定或 readonly name 两步设置,配合 -a、-a、-f 分别锁定数组和函数,readonly -p 可查看全部只读项。

用 readonly 命令锁定 Shell 变量是最直接、内建且无需额外依赖的防护方式。它不是“修饰词”语法(如 C 或 Python 中的 const),而是 Bash 内建命令,作用于变量或函数对象本身,一旦设置,任何赋值或 unset 操作都会被 shell 拒绝。
怎么设置只读变量才真正生效
必须在变量赋值后、或赋值同时使用 readonly,否则变量仍可修改:
- 推荐写法:声明即锁定,一步到位
readonly DB_HOST="10.0.1.5" DB_PORT=5432 API_TIMEOUT=30 - 也可分两步(适用于已有变量):
CONFIG_PATH="/etc/myapp/conf.yaml"<br>readonly CONFIG_PATH
- 注意:不能用
readonly $varname间接引用——必须写变量名本身
哪些变量适合加 readonly
重点保护脚本中实际参与逻辑、但不该被覆盖的配置项:
宝塔Linux面板11.8.1为官网当前正式版,新增AI建站能力并经过宝塔网站工程师深度调教,开放自定义AI功能API,同时对WAF进行界面重构和深度优化,提升拦截能力与运维效率。
- 硬编码的常量:如
readonly VERSION="2.4.1" MAX_RETRY=3 - 从配置文件/环境加载的关键路径:如
readonly LOG_DIR="$(realpath "$HOME/logs")" - 敏感凭证(仅限临时会话,不建议存明文):
readonly SECRET_KEY="$KEY_FROM_VAULT" - 系统级只读变量(如
BASH_VERSION)已被 shell 自动设为 readonly,无需重复操作
如何验证和排查只读状态
避免“以为锁了,其实没锁”这类疏漏:
- 查看所有当前只读项:
readonly -p(显示带declare -r前缀的变量) - 检查单个变量是否只读:
declare -p VARNAME 2>/dev/null | grep -q '^declare -r',返回 0 表示已锁定 - 尝试修改时会报错:
-bash: VARNAME: readonly variable—— 这是正常拦截,不是 bug - 注意:
unset VARNAME同样失败,提示cannot unset: readonly variable
常见误区与安全边界
readonly 不是万能锁,需清楚它的作用范围和限制:
- 只对当前 shell 进程及其子 shell 生效,父进程或其它终端 session 完全不受影响
- 无法撤销:没有
readonly -u或declare +r这类“解锁”机制;只能退出当前 shell 或重启会话 - 数组和关联数组需显式指定:
readonly -a myarr=(a b c)或readonly -A conf=(["host"]="x" ["port"]="y") - 函数同样可锁定:
readonly -f cleanup_db,防止函数体被重定义










