带引号的 ssh 命令

Spr*_*ips 17 shell ssh quoting

我有一个奇怪的错误,我一直无法找到任何关于此的信息。我想使用以下命令更改用户评论。

$ sudo usermod -c "New Comment" user
Run Code Online (Sandbox Code Playgroud)

这将在登录到服务器时工作,但我想在 20 多台服务器上实现自动化。通常我能够使用一个列表并遍历服务器并运行命令,但在这种情况下我会收到错误消息。

$ for i in `cat servlist` ; do echo $i ; ssh $i sudo usermod -c "New Comment" user ; done 
serv1
Usage: usermod [options] LOGIN

Options:
lists usermod options

serv2
Usage: usermod [options] LOGIN

Options:
lists usermod options
.
.
.
Run Code Online (Sandbox Code Playgroud)

当我运行这个循环时,它会抛出一个错误,比如我错误地使用了命令,但它会在单个服务器上运行得很好。

翻翻SSH手册页我曾尝试-t-t -t标志,但那些没有工作。

我已经成功地perl -p -i -e在类似的循环中使用来编辑文件。

有谁知道我无法循环的原因?

Gil*_*il' 26

SSH 在 shell 中执行远程命令。它将字符串传递给远程 shell,而不是参数列表。您传递给ssh命令的参数之间用空格连接。的参数sshsudo, usermod, -c, New Commentand user,所以远程 shell 会看到命令

sudo usermod -c New Comment user
Run Code Online (Sandbox Code Playgroud)

usermod解析Comment为用户名和user虚假的额外参数。

您需要将引号传递给远程 shell,以便将注释视为字符串。最简单的方法是将整个远程命令放在单引号中。如果您需要在该命令中使用单引号,请使用'\''.

ssh "$i" 'sudo usermod -c "Jack O'\''Brian" user'
Run Code Online (Sandbox Code Playgroud)

不要ssh在循环中调用并忽略错误,而是使用旨在在多个服务器上运行命令的工具,例如 pssh、mussh、clustersh 等。请参阅在许多服务器上通过 SSH 自动运行命令


小智 7

for i in `cat servlist`;do echo $i;ssh $i 'sudo usermod -c "New Comment" user';done
Run Code Online (Sandbox Code Playgroud)

或者

for i in `cat servlist`;do echo $i;ssh $i "sudo usermod -c \"New Comment\" user";done
Run Code Online (Sandbox Code Playgroud)