2

我在 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 次握手失败,但是当我通过以下方式从 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 中捕获输出。

4

2 回答 2

3

约翰布拉德的回答非常干净和可靠,但由于我对它的评论,我无法让它始终如一地工作:

即使在 wpa_supplicant.conf 中输入了无效凭据,iw wlan0 链接也会在短时间内显示它已连接。我假设它已连接,然后验证凭据,如果它们错误,则断开连接。所以这个脚本实际上不起作用,至少不是每次都起作用。

在该答案的帮助下,我最终做的是使用 -f 标志wpa_supplicant并将 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
于 2018-04-10T16:22:13.977 回答
2

它没有解决您的 Python 问题,但是(假设您有能力修改 BASH 脚本)您可以在 BASH 脚本中放置一个循环来检查输出iw wlan0 link并等待它返回成功消息或超时计数器到达。在建立连接之前,它将返回“未连接”。

在您调用 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
于 2018-04-08T18:58:30.713 回答