You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

shell脚本中su -c执行jmap堆转储命令失败求助

脚本执行失败的原因及修复方案

核心问题:单引号导致变量无法解析

你脚本里的su -c '${cmd}' $user使用了单引号,bash单引号内的变量不会被展开,tomcat用户实际执行的是字面命令${cmd},而不是你预先拼接好的jmap命令,这是脚本执行失败的直接原因。

修复方法

把单引号换成双引号,让bash能正常解析变量:

su -c "${cmd}" $user

其他潜在问题及优化建议

  • 环境变量不一致:脚本里source ~/.bash_profile加载的是root用户的环境变量,切换到tomcat用户后,jmap的路径可能不在其PATH中。可以改用su - $user -c "${cmd}"(-参数会让su加载目标用户的登录环境),或者直接使用jmap的绝对路径。
  • 多PID匹配风险:pgrep -f Bootstrap可能返回多个进程ID,导致process_id变量包含多个值,jmap命令会报错。可以改成process_id=$(pgrep -f Bootstrap | head -n1)只取第一个PID,或者用更精确的进程匹配规则。
  • 文件写入权限:确保/tmp目录tomcat用户有写入权限(默认/tmp是全局可写的,若自定义路径需额外检查)。

修复后的完整脚本示例:

#!/bin/bash

# Check to ensure we're running as root.
if [[ $EUID -ne 0 ]]; then
    echo "This script must be run as root. Either run as root or with sudo"
    exit 1
fi

if pgrep -f Bootstrap; then
    product="tomcat"
    user="tomcat"
    process_id=$(pgrep -f Bootstrap | head -n1)
else
    echo "Cannot find pid of running tomcat application"
    exit 1
fi

JmapPath=$(command -v jmap)
cmd="${JmapPath} -dump:format=b,file=/tmp/${product}_heapdump_$(date +%Y-%m-%d_%H-%M-%S).hprof ${process_id}"
echo $cmd
su - $user -c "${cmd}"

内容的提问来源于stack exchange,提问作者Zhang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 12:10:37