我正在尝试通过 SSH 运行如下命令:
ssh example.com <<END
sudo /etc/init.d/apache2 reload
END
这种方法通常有效,但当我尝试运行需要输入的程序(例如 sudo 的密码)时除外。在这种情况下,我收到以下消息:
sudo: no tty present and no askpass program specified
我知道我可以使用-t
SSH 上的标志来分配一个伪tty,例如:
ssh -t example.com "sudo /etc/init.d/apache2 reload"
它可以工作,但是当我尝试对此处的文档进行同样的事情时,它不起作用,并且我会收到关于没有 tty 存在的相同错误:
ssh -t example.com <<END
sudo /etc/init.d/apache2 reload
END
知道如何做才能让它工作吗?
此外,如果您想知道为什么我希望它与此处的文档一起工作而不是仅仅将其传递到同一行,那是因为输入命令(可能有几个)来自脚本读取的配置文件,我听说它避免了转义引号、双引号等命令的麻烦。
答案1
使用visudo
编辑 sudoers 文件并插入以下行:
Defaults:<user> !requiretty
它没有回答为什么使用
ssh -t "something" versus ssh -t <<STOP something STOP
不起作用。假设我没有使用 sudo,而是直接为自己的用户使用 passwd,我仍然无法使用 heredoc 获取 TTY。
即使 stdin 不是终端,也尝试ssh -t -t
强制分配伪 tty。
答案2
ssh -t
为什么不简单地将此处的文档存储在作为命令参数给出的变量中。
更一般地讲,ssh -T
如果远程主机的 stdin 正在从 heredoc 重定向,则使用或指定远程 shell 作为命令参数(以防止ssh
尝试分配 pty)。
# store heredoc in a variable
heredoc="$(cat <<EOF
who
sudo ls -ld /
logname
EOF
)"
ssh -t localhost "$heredoc"
# avoid: Pseudo-terminal will not be allocated because stdin is not a terminal.
- ssh example.com <<END
+ ssh -T example.com <<END
+ ssh example.com /bin/sh <<END