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
相关产品推荐
相关产品推荐

