plink与bash -c结合使用时首个命令无输出的根因咨询
plink与bash -c结合使用时首个命令无输出的根因咨询
这个问题我之前排查过类似的,咱们一步步拆解为啥会出现这种诡异的现象:
首先得搞清楚本地shell和远程shell的参数解析顺序:
当你在本地执行这条命令时:
plink -batch myuser@myhost bash -c 'echo one; echo two; echo three'
你的本地shell会先处理单引号——它会把单引号包裹的内容当作一个整体,但传递给plink的时候,单引号已经被本地shell去掉了!也就是说,plink实际传给远程主机的命令是:bash -c echo one; echo two; echo three
接下来看远程主机的登录shell(一般是bash)怎么解析这个命令:
- 远程shell会按分号把命令拆成三个独立的部分:
bash -c echo oneecho twoecho three
- 先执行第一部分
bash -c echo one:bash的-c选项规则是“把紧跟在-c后面的第一个参数作为要执行的命令”,剩下的参数会被当作新bash进程的$0、$1...(也就是shell的名称和位置参数)。所以这里echo被当成了要执行的命令,one变成了这个新bash的$0,而非echo的参数。实际执行的就是不带参数的echo,自然输出空行。 - 之后远程登录shell会继续执行后面的
echo two和echo three,这两个是直接由登录shell执行的,没有参数解析问题,所以能正常输出内容。
至于你说的workaround(加个无参数echo)能生效,本质是把原本被错误解析的echo one变成了后续的独立命令,避开了bash -c的参数陷阱,但其实更规范的解决方法是在本地用双引号把整个远程命令包起来,避免本地shell拆分参数:
plink -batch myuser@myhost "bash -c 'echo one; echo two; echo three'"
这样远程主机收到的就是完整的bash -c 'echo one; echo two; echo three',bash会把单引号内的所有内容当作一个完整命令执行,三个echo就能正常输出了。
备注:内容来源于stack exchange,提问作者IndustryUser1942
相关产品推荐
相关产品推荐

