使用Python通过SSH发送cqlsh命令的正确方法及常见报错解决方案
问题原因
- 第一层是引号转义冲突:你构造的cqlsh命令存在多层嵌套引号,经过本地shell、SSH远程shell两层解析后,引号结构被破坏,cqlsh收到的CQL语句不完整,触发语法报错
no viable alternative at input ':' - 第二层是参数错位或默认连接配置错误:引号解析异常后,多余的语句片段会被cqlsh识别为端口参数,触发
dsecqlsh.py not valid port报错;若未显式指定Cassandra监听地址,cqlsh默认连接127.0.0.1:9042,如果目标节点Cassandra未监听本地地址也会触发端口类报错。
解决方案
方法1:修正引号转义+调整subprocess调用方式
禁用shell=True避免本地shell额外转义,同时调整CQL语句的引号嵌套规则,确保两层shell解析后cqlsh能拿到完整的执行语句。
修改后代码如下:
def sshRemoteCmd(user,host,cmd): import subprocess # 改用列表传参,禁用shell=True避免本地转义问题 x = subprocess.Popen(["ssh", f"{user}@{host}", cmd], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() result='' if not x: result = 'error' else: for item in x: result += item.decode('utf-8', errors='ignore') return result # 转义内层单引号,确保远程解析后语句完整 # 如需指定cassandra连接地址端口,改成 cqlsh [你的CassandraIP] [端口] -e 'xxx' cmd = "cqlsh -e 'select * from MYTABLE where userid=\\'12345\\';'" result = sshRemoteCmd('root','hosts', cmd) print(result)
方法2:使用here document传递CQL语句(彻底避免转义问题)
如果CQL语句复杂、嵌套引号多,可以直接通过标准输入给cqlsh传命令,不需要处理-e参数的转义:
# 此处不需要处理引号嵌套 cql_stmt = """ select * from MYTABLE where userid='12345'; """ cmd = f"cqlsh << EOF\n{cql_stmt}\nEOF" result = sshRemoteCmd('root','hosts', cmd)
内容的提问来源于stack exchange,提问作者Alex Lu
相关产品推荐
相关产品推荐

