我有一台家用电脑(我们称之为富兰克林因为我就是这么称呼它的),我经常从我的工作笔记本电脑上进行 ssh 访问。当我在家时,我通过 ssh 访问 Franklin.local,当我在工作或其他任何地方时,我通过 ssh 访问remote.address.of.franklin。
我希望我的个人资料中有一个功能,可以根据具体情况始终以正确的方式进行连接。我的网络条件经常发生变化(有线与无线、不同的 SSID 等),因此我不想通过检测网络状态来实现这一点,而是:
- 如果 Franklin 本地可用,则本地连接,
- 否则,远程连接
这是我现在使用的:
function franklin () {
ping -c 5 "franklin.local" > /dev/null
if [[ $? != 0 ]]
then
echo "franklin not available on local, so trying remote connection"
ssh -p 22 remote.address.of.franklin
else
echo "franklin available on local network, so trying local connection"
ssh [email protected]
fi
}
问题是,ping 需要时间。我的问题是:我可以同时执行两个 ssh 命令,然后自动使用第一个连接的命令吗?
答案1
OR
从你的 shell 中尝试一个简单的怎么样?
ssh [email protected] || ssh -p 22 remote.address.of.franklin
我对 ZSH 不太熟悉,但我猜评估逻辑仍然是懒惰的,这意味着只有在第一部分失败时才评估第二部分。当然,第一个命令可能会停滞一段时间来尝试确定是否franklin.local
可用。
您可以将该命令分配给别名以缩短它(就像您对该函数所做的那样)。
答案2
我用nc
而不是 ping:
franklin() {
local host=franklin.local
if nc -w1 $host 22 &>/dev/null; then
echo "connecting locally"
else
echo "connecting remotely"
host=remote.address.of.franklin
fi
ssh username@$host "$@"
}
我添加"$@"
到 ssh 调用中。这可以让您快速执行远程命令,例如
franklin uptime
答案3
事实证明我比我想象的更接近解决方案。我对 ping 的地址查找部分如何工作有一个错误的假设。我认为如果网络出现问题,并且 Franklin.local 没有返回 ping,那么它就会失败并进行远程连接。事实证明,如果 Franklin.local 在网络上,ping -c 1 franklin.local
则返回 0,如果不在网络上,则返回 68,两者都立即返回。所以唯一的变化是 ping 计数从 5 变为 1(我还调整了脚本的顺序以使其更有意义):
function franklin
{
ping -c 1 franklin.local &> /dev/null
if [[ $? == 0 ]]; then
echo "Connecting locally."
ssh "[email protected]"
else
echo "Connecting remotely."
ssh "remote.address.of.franklin"
fi
}
这比我之前的速度快得多,并且比直接使用适当的 ssh 命令慢不了多少。