我有一个命令,我可以在Linux服务器上运行它而不会出现任何问题(让我们称之为server 1)。
在这里
myuser@server1: find -L /data* -type d -maxdepth 2 | xargs -d $'\n' sh -c 'for arg do echo "$arg" $(stat -f -L -c %T "$arg") ; done'
这将列出server 1目录树中两级以下的所有目录,并显示每个目录的关联文件系统。
现在,我想做的是在对server 1执行ssh-ing之后,从驻留在远程服务器(我们称之为server 2)上的bash脚本中运行完全相同的命令,但要将输出写入server 2上的文件。
myuser@server2: ssh "myuser@server1" "find -L /data* -type d -maxdepth 2 | xargs -d $'\n' sh -c 'for arg do echo "$arg" $(stat -f -L -c %T "$arg") ; done'" >output.txt
但是我似乎找不到正确的语法。我认为上面的命令做变量扩展不正确。你能帮忙吗?
谢谢你-格里戈
2条答案
按热度按时间xlpyo6sf1#
不使用xargs和pipe,而是重新排列命令:
g6ll5ycj2#
您作为远程命令给予给ssh的字符串在被发送到远程机器进行解析和执行之前,需要在本地机器上进行正常的解析。
在第二个示例中,当bash对命令行求值时,它在运行
ssh
之前,按照常规的参数扩展规则用$arg
替换其值。这意味着实际发送到远程计算机的命令是for arg in 1 2 3 ; do echo ; done
。有很多很好的建议可以解决BashFAQ上的这个问题。
1.手动重新引用。在我的简单示例中,可以使用单引号而不是双引号来保护字符串不被求值。由于嵌入了单引号,代码稍微复杂一些,因此必须通过将每个单引号替换为
'\''
来处理转义。1.使用stdin而不是命令行。例如,heredoc可以让你将命令传递到远程机器,而不需要太多的手动格式化。
1.如果远程shell是Bash,则使用
printf %q
之类的工具。这将格式化一个字符串,使其可以像ssh
那样安全地计算两次。