我想将 ssh 的输出通过管道传输到另一个命令。例如:
ssh myserver cat remote-file | diff local-file -
问题是 myserver 要求输入密码,但我无法输入。 (由于某种原因,公钥身份验证在服务器上不可用。我无法更改此设置。)我收到“密码:”提示,但我键入的密钥会回显,并且不会传递到 ssh。如何让ssh获取密码?
请注意,我并不想将密码通过管道传输到 ssh。我正在尝试通过管道传输 ssh 的输出,并像往常一样输入密码。
以防万一,我在 OS X 10.7 (Lion) 上使用 bash 和标准终端。我没有设置可能导致此问题的别名。我在不同的(Linux)系统上看到过同样的问题,所以我相信这不是我的设置所特有的。
答案1
好吧,事实证明这是由于与我的 bash 配置的奇怪交互造成的。
我有一些东西.bash_profile
可以将当前执行的命令放入窗口标题或screen
选项卡中。它的工作原理是使用trap
:
trap 'bash_current_command' DEBUG
在此之前:
function bash_current_command {
# only works in bash > 3.1
#set -- $BASH_COMMAND
# for old bash
set -- $(history 1)
shift
if [[ "$1" == "sudo" ]]; then
cmd="*$(basename -- "$2")*"
else
cmd="$(basename -- "$1")"
fi
bash_set_title "$cmd"
}
bash_set_title
是一个使用 ANSI 转义码设置当前终端标题和图标标题的小函数。正如您所看到的,这会创建 subshells $(...)
,我的直觉告诉我这可能是问题所在。事实上,在我改变这些行之后,它起作用了!
如果有人知道为什么会发生这种情况,我很高兴听到详细信息。子 shell 通常会窃取tty
输入吗?或者这只是调试陷阱中的问题?我不记得常规stdin
输入/管道命令的问题。
(正如您还可以看到的,我的函数无论如何都存在一些问题 - 它使用其中一个子 shell 作为解决方法,因此它可以在古老的 bash 版本上运行(我在遗留系统上坚持使用它,但仍然想要一个统一的配置)。另一个子shell用于在使用时提取实际命令sudo
,但是如果使用像这样的开关调用sudo,则会失败sudo -H -u user command
,所以我将其视为修复此代码的机会...)
答案2
此答案并未解释您的具体问题,但提供了一些可能的解决方法,这些解决方法也可能使您的生活更加方便。
如果您仅使用 ssh 访问远程文件而不运行远程命令,那么您可以通过以下方式挂载远程文件系统sshfs。你需要安装OS X 的保险丝和SSHFS第一的。 (我不知道是否有 OSX 的二进制发行版。)然后运行
mkdir ~/myserver
sshfs myserver:/ ~/myserver
仅当运行该命令时才需要进行身份验证sshfs
。之后,远程文件就可以在 下使用~/myserver
,因此您可以diff ~/myserver/path/to/remote-file local-file
不必担心其中一个文件是远程的。运行fusermount -u ~/myserver
以卸载文件系统。
另一种允许您进行一次身份验证然后运行许多 ssh 命令的方法是设置主连接。看重复使用 ssh 会话来执行 rsync 命令