我正在尝试在 ubuntu 主机上远程运行 shell 脚本。
我可以使用 me@host 顺利 ssh 到机器。
在远程机器上,我可以运行 sudo 命令,而无需输入密码。
我可以使用 rsh 在远程主机上运行 shell 命令
现在我输入 sudo 命令但出现错误
sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper
我运行的命令如下:
ssh user@hostIPAddress "cd /opt/somewhere && sh -v -v ./install.sh"
install.sh 包含一个需要 sudo 命令的命令
#!/bin/bash
sudo pm2 stop someprocess
我该如何解决这个错误?
答案1
如果您不想sudo
提示输入密码,在了解安全隐患后,您可以编辑该sudoers
文件。但是,直接编辑该文件并不安全。相反,请使用:
sudo visudo
为了允许在没有密码的情况下运行特定程序,请添加一行sudoers
格式:
YOURNAME ALL = NOPASSWD: /path/to/pm2 stop someprocess
上面,YOURNAME
用您在该系统上的登录名替换,并/path/to/pm2
用该程序的完整路径替换( 的输出which pm2
)。
如果你想允许pm2
无密码运行任何参数,而不仅仅是stop someprocess
,然后从该行中删除最后两个单词。
有关编辑的更多信息sudoers
,请参阅如何在没有密码的情况下使用 sudo 运行应用程序和man sudoers
和man visudo
。
答案2
改变行为ssh
当您ssh
不使用命令运行时,如果存在本地伪终端,该工具会自动在远程端分配一个伪终端。通常,您会以这种方式访问交互式远程 shell,因此分配终端是正确的做法。
当您向 提供远程命令时ssh
,它会假定该命令不是交互式的。它不会为该命令提供伪终端。在您的案例中,会发生这种情况,sudo
找不到终端。
您可以明确地告诉本地ssh
在远程端分配一个伪终端:
-t
强制分配伪终端。这可用于在远程机器上执行任意基于屏幕的程序,这非常有用,例如在实现菜单服务时。多个-t
选项强制分配 tty,即使ssh
没有本地 tty。
(来源)
ssh -t user@hostIPAddress "cd /opt/somewhere && sh -v -v ./install.sh"
请注意,当您这样做时,您无法再./install.sh
在本地区分 stdout 和 stderr。请阅读“更广阔的视野”部分这是我的另一个答案。
改变行为sudo
sudo
建议仅依赖于其sudo
自身的替代解决方案:
sudo
:需要终端来读取密码;可以使用-S
从标准输入读取的选项,也可以配置 askpass 助手
这些都是:
两者都需要参数sudo
,因此您需要更改脚本。使用任何这些选项都很容易降低安全性。非常喜欢ssh -t
。一般注意事项sudo
可能配置为在没有终端的情况下无法工作。