我遇到了一个非常奇怪的问题。我正在扩展一个Raspberry Pi 的操作系统安装程序。我将其配置为在安装程序完成其工作后自动启动,并运行我的脚本来完成剩余的安装。但有时我想重新安装我的附加组件,而不重新安装整个操作系统。所以我有一个名为首次登录时像这样:
if [ $(command -v git) ]; then
echo "Git already installed."
else
apt-get install git -y
fi
git clone [email protected]:me/my-repo.git ~/my-repo
现在到了真正奇怪的部分。上面的代码仅在需要安装 git 时才有效,或者如果我将脚本更改为以下内容:
apt-get install git -y
git clone [email protected]:me/my-repo.git ~/my-repo
否则我会收到此错误:
ssh:无法解析主机名 github.com:名称或服务未知
我确实想解决这个问题,主要是出于原则,但也为了避免调用,apt-get install git -y
因为它需要大约 5 秒(如果已经安装了 git),这有点痛苦。
我尝试让脚本等待 ping 成功,如下所示:
if [ $(command -v git) ]; then
echo "Git already installed."
else
apt-get install git -y
fi
pingerr=1
while [ $pingerr ]; do
sleep 1
ping -c 1 github.com | grep "1 received"
pingerr=$?
if [ $pingerr ]; then
echo "Could not ping github. Retrying..."
else
echo "Successfully pinged github"
fi
done
git clone [email protected]:me/my-repo.git ~/my-repo
但它只是无限地重试。
到底发生了什么事?它似乎apt-get install
在做一些特别的事情,我很想知道是什么。
答案1
正如您已经发现的那样,您的网络git clone
在完全连接之前就会被调用。它唯一的魔力apt-get
可能就是需要一点时间来查询本地包数据库。这给了网络足够的时间来启用和配置。
您的第二个脚本无法正常运行的原因在于您混淆了程序返回代码。在 bash 或一般的 shell 中,数字零表示 TRUE 布尔值。成功退出的程序应返回数字零。因此,如果您的 ping(和 grep)成功,您将获得零返回值并将while 0
永远循环。
此外,您抓取的是 grep 命令的返回值,而不是直接方便地使用 ping。请尝试使用此脚本:
retries=0
while ! ping -c1 github.com >/dev/null 2>&1; do
sleep 1
if (( retries++ > 10 )); then
echo "Max retries reached, aborting." >&2
exit 1
fi
done
git clone [email protected]:me/my-repo.git ~/my-repo
为了增加详细程度,请从 ping 中删除输出重定向。
我想这是一个明显的警告,但是您的设置的安全性看起来很可疑——您正在使用 root 帐户自动从 git 下载东西……