使用sshpass通过SSH执行nmap时的引号转义问题咨询
解决sshpass远程执行命令时awk单引号冲突的问题
方案1:转义内层单引号
在bash的单引号环境中,内层单引号可以通过'\''的方式转义,以此避免和外层单引号冲突。修改后的命令如下:
sshpass -p "pass" ssh -o StrictHostKeyChecking=no user@ip 'nmap $(hostname -I | awk '\''{print $1}'\'')'
原理:'\''实际是三个部分的组合——先关闭外层单引号,插入转义后的单引号,再重新打开外层单引号,让远程shell正确识别awk的命令参数。
方案2:改用双引号包裹远程命令(注意转义$)
如果把外层的单引号换成双引号,内层awk的单引号就不需要转义,但要把$转义为\$,防止本地shell提前解析$(...)命令替换。修改后的命令:
sshpass -p "pass" ssh -o StrictHostKeyChecking=no user@ip "nmap \$(hostname -I | awk '{print $1}')"
注意:如果不转义$,本地会先执行hostname -I | awk '{print $1}',把结果作为参数传给远程的nmap,而非让远程主机自己执行这个IP提取命令。
方案3:使用本地脚本传递命令
对于复杂的远程命令,最稳妥的方式是把命令写到本地脚本中,再传到远程执行:
- 本地创建脚本文件
scan.sh:
#!/bin/bash nmap $(hostname -I | awk '{print $1}')
- 用sshpass配合scp上传脚本并执行:
sshpass -p "pass" scp scan.sh user@ip:/tmp/ sshpass -p "pass" ssh -o StrictHostKeyChecking=no user@ip 'chmod +x /tmp/scan.sh && /tmp/scan.sh'
这种方式完全避免了引号嵌套的问题,适合后续需要修改或扩展命令的场景。
方案4:通过Here-doc传递命令
使用Here-doc( heredocument)可以直接传递多行命令,且无需处理引号转义,只需用单引号包裹EOF标记,确保本地shell不解析内部变量:
sshpass -p "pass" ssh -o StrictHostKeyChecking=no user@ip << 'EOF' nmap $(hostname -I | awk '{print $1}') EOF
EOF标记用单引号包裹后,所有内部的命令和变量都会原封不动地传递给远程shell执行。
内容的提问来源于stack exchange,提问作者Koren
相关产品推荐
相关产品推荐

