远程SSH执行脚本未打印变量值及hostname异常问题求助
问题分析与解决办法
问题1:变量无法打印,仅输出等号
你用双引号包裹SSH远程命令时,本地Shell会优先解析$a、$b、$c这些变量,但本地并未定义它们,导致这些变量被替换为空字符串。最终远程执行的命令变成了echo === === === ===,自然只输出等号。
解决办法:
- 用单引号包裹远程命令,本地Shell不会解析里面的变量,所有内容会原封不动传给远程服务器执行;
- 如果必须用双引号,需把变量前的
$转义为\$(比如\$a)。
问题2:hostname返回内核版本
这是因为远程服务器的hostname命令被覆盖了:要么是用户设置了别名(比如alias hostname='uname -r'),要么是PATH里存在自定义的hostname脚本/程序,优先级高于系统默认命令。
解决办法:
- 直接使用系统
hostname命令的绝对路径(可在远程服务器用which hostname查看正确路径,比如/bin/hostname); - 改用
uname -n命令,它直接输出主机名,不受别名影响; - 检查远程的
~/.bashrc、~/.bash_profile等配置文件,删除hostname的别名设置。
优化后的实现方案
优化点:
- 去掉冗余的
grep和sed,直接用awk完成过滤取值,提升效率; - 使用语义化变量名,增强代码可读性;
- 强制调用系统
hostname命令避免别名干扰; - 直接输出标准CSV格式,无需额外处理分隔符。
# 远程执行命令并获取CSV结果 remote_result=$(ssh -q user@host ' # 获取总内存(单位:GB) total_mem=$(free -g | awk "/Mem/{print $2}") # 获取CPU核心数 cpu_cores=$(lscpu | awk "/^CPU\(s\)/{print $2}") # 获取主机名(使用系统命令绝对路径) host_name=$(/bin/hostname) # 输出CSV格式内容 echo "$total_mem,$cpu_cores,$host_name" ') # 打印结果,双引号包裹避免字段含空格时被拆分 echo "$remote_result"
如果需要批量处理多台主机,可扩展为循环:
# 定义待处理主机列表 target_hosts=("user@host1" "user@host2" "user@host3") for host in "${target_hosts[@]}"; do echo "--- 处理主机:$host ---" remote_result=$(ssh -q "$host" ' total_mem=$(free -g | awk "/Mem/{print $2}") cpu_cores=$(lscpu | awk "/^CPU\(s\)/{print $2}") host_name=$(/bin/hostname) echo "$total_mem,$cpu_cores,$host_name" ') echo "$remote_result" done
内容的提问来源于stack exchange,提问作者Sudharsan Simhan




