SSH远程执行Redis命令多行改写报错问题求解
问题成因
- 你尝试的多行版本使用
双引号包裹需要远端执行的命令块,Shell默认会在本地先解析双引号内的所有$()命令替换、$变量引用,因此$(redis-cli scan 0)、$(redis-cli get $key)等代码根本没有传到远端服务器,是在本地机器提前执行的,所以才会在SSH验证前就报本地Redis连接失败的错误。 - 原始单行版本使用
单引号包裹命令块,单引号会阻止本地Shell的变量/命令替换,所有内容会原封不动传给远端服务器执行,因此可以正常运行。
正确的多行实现方案
方案1:使用带引号的Here Document(可读性最优)
用<<'EOF'的形式传递命令块,单引号包裹EOF标记可以完全阻止本地Shell提前解析内容,所有命令会在远端执行:
results=$(ssh "$server" <<'EOF' keys=$(redis-cli scan 0) keypairs="" for key in $keys do value=$(redis-cli get $key) keypairs="$keypairs$key $value\n" done echo "$keypairs" EOF )
如果遇到ssh读取标准输入异常的情况,可以给ssh加-n参数:ssh -n "$server"。
方案2:延续单引号包裹的写法
直接用单引号包裹多行命令即可,只要单引号不中途闭合,内容会原样传给远端:
results=$(ssh "$server" ' keys=$(redis-cli scan 0) keypairs="" for key in $keys do value=$(redis-cli get $key) keypairs="$keypairs$key $value\n" done echo $keypairs ')
额外注意事项
当前用的redis-cli scan 0只会返回第一页的key,如果你Redis实例的key数量超过默认计数(默认10),会出现漏取的情况,生产环境建议用循环扫描的逻辑处理scan返回的游标。
内容的提问来源于stack exchange,提问作者AaronHaNasi
相关产品推荐
相关产品推荐

