我在Raspberry Pi上有一个Python / Flask Web应用程序,它调用以下bash脚本( connect_to_wifi )来连接到WiFi:
sudo killall wpa_supplicant
sudo wpa_supplicant -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf
sudo dhclient wlan0
基本上,用户输入他们的WiFi凭据,这些凭据保存在wpa_supplicant.conf
中,然后运行此脚本。它工作得很好......但是,如果他们输入错误的凭据,dhclient会在失败前挂起永远。
我想要做的是在继续使用dhclient之前检测凭据是否正确。我知道如果信用证错误,我可以检查wpa_supplicant
命令的输出是否存在4-Way Handshake故障,但是当我从Python应用程序通过以下方式调用此脚本时:
p = Popen(['connect_to_wifi'], stdout=PIPE, bufsize=1)
with p.stdout:
for line in iter(p.stdout.readline, b''):
print line,
p.wait()
没有捕获sudo wpa_supplicant -i...
行的输出。如果我发现握手失败,我想做的就是立即结束,但我在使用Python捕获输出时遇到了麻烦。
答案 0 :(得分:2)
John Bullard的回答非常干净而且非常可靠,但由于我对其做出的评论,我无法让它始终如一地工作:
有一个短暂的时期,即ww0链接表示它连接均匀 如果在wpa_supplicant.conf中输入了无效凭证。我'米 假设它连接,然后验证信用,如果他们错了, 断开。所以这个脚本实际上并不起作用,至少不是每个 时间。
我最后做的是,在答案的帮助下,使用wpa_supplicant
的-f标志并将wpa_supplicant的输出写入文件。 while循环然后greps连接状态,在这种情况下它将调用dhclient
。如果它没有连接,它将超时或导致4次握手失败(如果后者,脚本将提前结束)。
#!/bin/bash
sudo ip addr flush dev wlan0
sudo killall wpa_supplicant
sudo truncate -s 0 wifi_connection_status.txt
sudo wpa_supplicant -B -i wlan0 -f wifi_connection_status.txt -c /etc/wpa_supplicant/wpa_supplicant.conf
declare -i i=0
declare -i timeout=15
while [ $i -le $timeout ]; do
if grep -iq 'CTRL-EVENT-CONNECTED' wifi_connection_status.txt; then
sudo dhclient wlan0
exit 2
elif grep -iq '4-Way Handshake failed' wifi_connection_status.txt; then
exit 2
fi
(( i++ ))
sleep 1
done
答案 1 :(得分:1)
它没有解决你的Python问题,但是(假设你有能力修改BASH脚本)你可以在BASH脚本中放一个循环来检查iw wlan0 link
的输出并等待它要么返回成功消息,要么达到超时计数器。在建立连接之前,它将返回“Not Connected”。
在之前只需调用dhclient,你就应该确定要运行的有效连接。
有些事情:
sudo killall wpa_supplicant
sudo wpa_supplicant -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf
declare -i waitcount=0;
while sudo iw wlan0 link | grep -iq "Not connected"; do
((waitcount+=1))
if (( waitcount > 30 ))
then
echo;
echo "Timeout while waiting for successful association and authentication."
exit 2;
fi
sleep 1s;
echo -n ".";
done
sudo dhclient wlan0