HOME

麒麟 V10 安装 IBM MQ 9.0.5 误报必须使用 root:中文 Locale 导致的 mqlicense.sh 判断失败

文章目录8 节

麒麟 V10 安装 IBM MQ 9.0.5 误报必须使用 root:中文 Locale 导致的 mqlicense.sh 判断失败

一、先说结论

在麒麟 Linux V10 上执行 IBM MQ 9.0.5 的 mqlicense.sh -accept 时,即使终端提示符已经是 root,脚本仍然可能报错:

ERROR: You must be 'root' to run this script.

这次问题不是 root 权限不足,而是中文 Locale 改变了 id 命令的可读文本。麒麟实验机的实际有效 UID 是 0,但中文环境下 id 输出为“用户id=0(root)”;切换到 C Locale 后才输出旧脚本通常匹配的“uid=0(root)”。

修复时不需要修改系统全局语言,也不需要先改 IBM MQ 脚本。核心处理是只为接受许可这一条命令临时指定英文 Locale,完整命令、影响和验证方法见第五节。

这篇文章保留了原始踩坑过程、目标机补充截图、实验机上的 Termark 证据和可复用的修复命令。两张截图中的主机名已遮盖;实验机本次没有在有限检查目录中找到完整的 IBM MQ 安装介质,因此文中不会把“实验室完成了完整 MQ 安装”写成已验证事实。

二、最容易误导人的现象:提示符是 root,但脚本说不是

原始操作是在解压后的 MQServer 目录中执行:

[root@<已脱敏主机名> MQServer]# ./mqlicense.sh -accept
ERROR: You must be 'root' to run this script.

IBM MQ mqlicense.sh 误报 root 的终端截图(主机名已遮盖)

截图还有一个很有价值的线索:ls 把月份显示成了“3月”。这说明当前会话正在使用中文区域设置。文件列表中出现的数字属主 226:12201 是安装介质保存的文件元数据,不是当前 shell 的有效用户;判断脚本能否以 root 运行,应该看进程的有效 UID。

补充截图记录了修复命令:

IBM MQ mqlicense.sh 使用 C Locale 后的许可材料与发行版警告(主机名已遮盖)

这次 LC_ALL=C LANG=C ./mqlicense.sh -accept 后,原来的 You must be 'root' 没有再次出现,脚本继续显示 IBM Licensed Materials;但同时给出:

WARNING: Unable to determine distribution and release for this system.
Check that it is supported before continuing with this installation.

这说明第一层的 root 判断已经通过,发行版支持性是另一个需要单独核对的问题。它不能被“没有 root 报错”掩盖,也不能仅凭这张图宣称 MQ RPM 已经安装完成。

三、先验证有效 UID,不要把提示符当成权限证据

下面这组命令只读取当前会话的身份和 Locale。它适用于麒麟或其他 Linux 主机的当前 shell,不会修改系统配置;预期 id -u 输出 0id -unwhoami 输出 root

风险等级:INFO(只读)

作用: 区分“提示符文字”与进程实际有效身份,并确认是否启用了中文 Locale。 执行对象: 当前麒麟 Linux shell;可以是 root 控制台,也可以是通过 SSH 登录的 root 会话。 完成验证: id -u0,并且 id -unwhoami 均为 root

id
id -u
id -un
whoami
locale

我通过 Termark 在一台脱敏后的麒麟实验机上得到的关键结果是:

操作系统:Kylin Linux Advanced Server V10 (Lance)
LANG=zh_CN.UTF-8
LC_MESSAGES="zh_CN.UTF-8"
uid_numeric=0
user_name=root
whoami=root

但是,同一台机器在中文 Locale 下执行 id,输出文本是:

用户id=0(root) 组id=0(root) 组=0(root)

因此,“看到 root@... 提示符”与“脚本一定能识别 root”是两件事:前者只是 shell 提示符,后者取决于脚本实际采用的判断方式。

四、用 C Locale 对比,复现脚本误判条件

LC_ALL=C LANG=C 只对当前命令及其子进程生效。下面的对比仍然是只读检查,不会改变系统 Locale;它把 id 恢复为传统的英文输出格式。

风险等级:INFO(只读)

作用: 比较中文 Locale 与 C Locale 下 id 的输出,确认旧式英文文本匹配是否会失效。 执行对象: 当前 Linux shell;无需安装组件或停止服务。 完成验证: 中文环境下的英文文本匹配为 match=noC Locale 下为 match=yes,而数字 UID 检查仍为 root=yes

printf '[当前 Locale]\n'
id

printf '[C Locale]\n'
LC_ALL=C LANG=C id

printf '[模拟旧式英文文本判断]\n'
if id | grep -qF 'uid=0(root)'; then
    printf 'current-locale-match=yes\n'
else
    printf 'current-locale-match=no\n'
fi

if LC_ALL=C LANG=C id | grep -qF 'uid=0(root)'; then
    printf 'C-locale-match=yes\n'
else
    printf 'C-locale-match=no\n'
fi

if [ "$(id -u)" -eq 0 ]; then
    printf 'numeric-root=yes\n'
else
    printf 'numeric-root=no\n'
fi

实验机的输出是:

[当前 Locale]
用户id=0(root) 组id=0(root) 组=0(root)

[C Locale]
uid=0(root) gid=0(root) groups=0(root)

current-locale-match=no
C-locale-match=yes
numeric-root=yes

这组结果把问题边界定得很清楚:有效 UID 没有变化,变化的只有 id 的可读文本。旧版安装脚本如果通过匹配 uid=0(root) 这样的文本来判断 root,就会在中文 Locale 下误报;如果用 id -u 判断,则不会受翻译文本影响。

五、修复:只为 mqlicense.sh 临时使用英文 Locale

确认 id -u0、当前目录确实是解压后的 MQServer 目录,并且已经阅读要接受的 IBM MQ 许可后,再执行下面的命令。LC_ALL=C LANG=C 是命令级环境变量,不会把麒麟系统永久切换成英文;-accept 只完成许可证接受步骤,不等同于安装所有 MQ RPM。

风险等级:CAUTION(接受软件许可,可能记录许可状态)

作用: 绕过旧脚本对中文 id 输出的脆弱文本匹配,让 mqlicense.sh 在英文 Locale 下识别实际的 UID 0。 执行对象: 解压后的 IBM MQ MQServer 目录;命令需要 root 权限。 执行前检查: 先确认 id -u 输出 0,当前目录包含 mqlicense.sh,并确认接受对应版本的 IBM MQ 许可。 影响与恢复: 该命令不会修改系统全局 Locale,也不会替代后续 RPM 安装。若尚未同意许可,不要执行;若需要丢弃解压目录,可删除或重新解压安装介质,但不要把这个动作误认为 MQ 卸载。 完成验证: 脚本不再输出 root 误报,并出现该版本脚本的许可接受成功提示;随后仍要单独检查 RPM 安装状态。

# 进入解压后的 IBM MQ 安装介质目录;按实际路径替换此处路径
cd /path/to/MQServer

# 先确认当前 shell 的有效 UID,必须输出 0
id -u

# 只对这一次许可接受命令使用英文 Locale
LC_ALL=C LANG=C ./mqlicense.sh -accept

如果当前 shell 的 id 命令路径异常,可以在确认系统实际命令位置后再使用下面的等价写法。它仍然是一次性的 Locale 设置,且同样会执行许可证接受;不要把它当成通用的 MQ 安装命令。

风险等级:CAUTION(接受软件许可,可能记录许可状态)

作用: 同时固定常见系统命令目录,避免异常 PATH 影响脚本调用 id 等基础命令。 执行对象: 当前 Linux shell 和解压后的 MQServer 目录;需要 root 权限。 完成验证: 与上一条命令相同,确认脚本不再出现 root 误报,并单独验证后续 RPM 状态。

PATH=/usr/sbin:/usr/bin:/sbin:/bin \
LC_ALL=C LANG=C \
./mqlicense.sh -accept

不建议一上来修改 /etc/locale.conf、用户 profile 或系统语言。这个问题只需要让许可脚本在一次调用中看到稳定的英文 id 输出,改全局配置会扩大变更范围,也可能影响其他程序的日志、排序和日期格式。

六、许可接受不等于 MQ 已安装

mqlicense.sh -accept 的作用是接受许可并允许继续安装。无论脚本是否成功,都应该把“许可状态”和“RPM 安装状态”分开验证。下面命令是只读检查,适合在许可证步骤之后执行:

风险等级:INFO(只读)

作用: 确认是否已经安装 MQSeries* RPM,以及 MQ 默认目录和版本命令是否出现。 执行对象: 目标 Linux 主机;不安装、不删除、不重启服务。 完成验证: 根据操作阶段解释结果:许可接受后、RPM 安装前,rpm -qa 可能无输出,/opt/mqmdspmqver 也可能尚未存在;只有完成 RPM 安装后才应期待这些证据。

rpm -qa | grep -E '^MQSeries' | sort || true
ls -ld /opt/mqm 2>/dev/null || echo '/opt/mqm not present yet'
command -v dspmqver || echo 'dspmqver not in PATH yet'

这里的 || true 只是让“没有匹配项”不把检查序列变成失败;它不会伪造安装结果。判断安装是否完成时,应结合 RPM 数据库、/opt/mqmdspmqver 和版本输出,而不能只看到“Agreement accepted”就下结论。

七、如果设置 C Locale 后仍然失败

如果 LC_ALL=C LANG=C ./mqlicense.sh -accept 仍报错,不要继续猜测。先确认脚本使用的 id 到底来自哪里,并读取它的 root 判断片段。下面仍是只读诊断;变量 MQSERVER_DIR 的值必须替换为实际解压目录,不要对 / 做递归搜索。

风险等级:INFO(只读)

作用: 排除 PATH、命令别名、脚本解释器和安装介质损坏等第二层问题。 执行对象: 解压后的 MQServer 目录和当前 shell;不会修改脚本。 完成验证: type id 应指向系统的 id 命令;id -u 仍应为 0;脚本首行和有限范围内的 root 判断代码可读。

MQSERVER_DIR=/path/to/MQServer
cd "$MQSERVER_DIR"
type id
command -v id
id -u
head -n 1 ./mqlicense.sh
grep -nE 'root|uid|whoami|id[[:space:]-]' ./mqlicense.sh | head -40

可能的后续原因包括:实际有效 UID 并不是 0、脚本调用了异常的 id、脚本解释器与当前系统不兼容、安装介质被截断,或者当前 MQ 版本与麒麟发行版组合不在厂商支持范围内。它们与 Locale 误判是不同问题,应分别取证。

八、这次实验得到的可复用结论

  1. root@主机名 只是提示符,不能替代 id -u 对有效 UID 的验证。
  2. id 的可读输出会受到 Locale 影响;脚本解析人类可读文本时,中文系统尤其容易暴露兼容性问题。
  3. LC_ALL=C LANG=C command 是处理旧版脚本 Locale 兼容性的最小变更,优先级高于修改系统全局语言或直接改厂商脚本。
  4. mqlicense.sh -accept 只处于许可证接受层,后面仍需要用 RPM 数据库、/opt/mqmdspmqver 验证实际安装状态。
  5. 本次补充截图已证明原始目标机在 C Locale 下越过了 root 判断并进入许可材料输出;Termark 实验进一步验证了麒麟 V10 的 UID、Locale 和误判条件。完整 IBM MQ 9.0.5 RPM 安装仍不在本次证据范围内,因此不能把发行版兼容性或 MQ 安装完成写成已验证结论。

对生产环境而言,建议先在与目标系统同版本的测试机上用命令级 Locale 覆盖验证许可脚本,再决定是否纳入自动化安装流程。不要用全局 Locale 修改掩盖其他安装错误,也不要为了绕过一条提示就直接编辑厂商安装脚本。

IBM MQ 麒麟 Linux Linux Locale 故障排查 兼容性