You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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:使用本地脚本传递命令

对于复杂的远程命令,最稳妥的方式是把命令写到本地脚本中,再传到远程执行:

  1. 本地创建脚本文件scan.sh:
#!/bin/bash
nmap $(hostname -I | awk '{print $1}')
  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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 09:57:38