【问题标题】:Edit wpa_supplicant.conf with python and raspbian使用 python 和 raspbian 编辑 wpa_supplicant.conf
【发布时间】:2019-05-12 15:50:02
【问题描述】:

愿意从 kivy 应用程序添加 wifi 连接,我正在使用一个简单的函数来编辑 wpa_supplicant.conf 文件添加新网络。

我的函数在那里正确写入了配置,并且似乎与通过 raspbian GUI 添加的配置相同...

但是当我重新启动树莓派时,它说没有找到网络接口,但是如果我从 wpa_supplicant.conf 文件中删除最后添加的行,它就会得到解决。由于某些原因,raspbian 在编辑后无法正确读取此文件,但我看不出我在这里做错了什么,这与默认配置不同。

希望有人能给我一些提示...我以 sudo 运行脚本,所以不可能有任何权限问题,我试图研究我编写配置的方式和 raspbian 提供的配置的任何差异,但没有线索...

这里可以看到代码:

def CreateWifiConfig(SSID, password):
        config = (
                '\nnetwork={{\n' +
                '\tssid="{}"\n' +
                '\tpsk="{}"\n' + '}}').format(SSID, password)
        print(config)
        with open("/etc/wpa_supplicant/wpa_supplicant.conf", "a+") as wifi:
            wifi.write(config)
        wifi.close()
        print("Wifi config added")```

【问题讨论】:

  • 很抱歉,您能告诉我其他方法是什么吗?我试试这个,但还是不行

标签: python raspberry-pi wifi raspbian wpa-supplicant


【解决方案1】:

这只是一条路过的评论——我没有运行你的代码,我只是根据我正在阅读的内容来解释它——但这里有几件事让我印象深刻:

1) 我在您的配置中没有看到 key_mgmt 值。通常这类似于WPA-PSK,但您可以看到一些额外的可能值here

2) 因为您使用的是the "with" statement,所以该文件应该会自动为您关闭(您不需要再次调用close())。

3) 你构建配置字符串的方式对我来说有点奇怪,像这样的东西怎么样(完全主观,对我来说更具可读性):

def CreateWifiConfig(SSID, password):
  config_lines = [
    '\n',
    'network={',
    '\tssid="{}"'.format(SSID),
    '\tpsk="{}"'.format(password),
    '\tkey_mgmt=WPA-PSK',
    '}'
  ]

  config = '\n'.join(config_lines)
  print(config)

  with open("/etc/wpa_supplicant/wpa_supplicant.conf", "a+") as wifi:
    wifi.write(config)

  print("Wifi config added")

4) 这里要注意的另一件事是此代码不是幂等的 - 您将无法在不影响文件内容完整性的情况下多次运行此代码。您可能已经意识到这一点并且可能并不特别在意,但还是要指出来。

希望丢失的key_mgmt 就是这样。

【讨论】:

  • 嗨,我问这个问题很久了,已经转向其他方法了......无论如何,非常感谢您花时间回答,我记得我复制了这个文件是完全相同的“视觉上”作为当我使用 GUI 连接到网络时生成 raspbian 本身的那个......所以我不认为 key_mgmt 缺少什么......另外,幂等性究竟意味着什么?如果我没记错的话,这段代码只是在配置文件中添加了额外的网络,你的意思是万一网络重复出现问题?
  • 不用担心 - 我实际上应该检查日期戳并认为:D
  • 但是再看一点,我也不完全确定 key_mgmt 是我自己现在的问题...阅读文档,它表明如果未设置,它将默认为无论如何都要使用WPA-PSK WPA-EA,这样你可能就知道了。但是“幂等”是指如果您运行该功能一次或一百次,它将使文件内容处于相同状态,即它将考虑当前状态并仅在必要时更新它。有更深入的解释here
【解决方案2】:

这是我添加或更新 wifi 的解决方案。 方法中的json 参数是一个具有值的字典: {"ssid": "wifi_name", "psk": "password"}。可以轻松修改此脚本以将 id_strpriority 添加到网络。

def command_add_wifi(json):
  print("-> Adding wifi")
  
  # Read file WPA suppliant
  networks = []
  with open("/etc/wpa_supplicant/wpa_supplicant.conf", "r") as f:
    in_lines = f.readlines()  

  # Discover networks
  out_lines = []
  networks = []
  i = 0
  isInside = False
  for line in in_lines:
    if "network={" == line.strip().replace(" ", ""):
      networks.append({})
      isInside = True
    elif "}" == line.strip().replace(" ", ""):
      i += 1
      isInside = False
    elif isInside:      
      key_value = line.strip().split("=")
      networks[i][key_value[0]] = key_value[1]
    else:
      out_lines.append(line)

  # Update password or add new
  isFound = False
  for network in networks:
    if network["ssid"] == f"\"{json['ssid']}\"":
      network["psk"] = f"\"{json['psk']}\""
      isFound = True
      break
  if not isFound:
    networks.append({
      'ssid': f"\"{json['ssid']}\"",
      'psk': f"\"{json['psk']}\"",
      'key_mgmt': "WPA-PSK"
    })

  # Generate new WPA Supplicant
  for network in networks:
    out_lines.append("network={\n")
    for key, value in network.items():
      out_lines.append(f"    {key}={value}\n")      
    out_lines.append("}\n\n")

  # Write to WPA Supplicant
  with open('/etc/wpa_supplicant/wpa_supplicant.conf', 'w') as f:
    for line in out_lines:
      f.write(line)

  print("-> Wifi added !")

【讨论】:

    【解决方案3】:

    我尝试使用 Python 脚本重写“wpa_supplicant.conf”文件,但整个 Wi-Fi 系统刚刚崩溃,我必须重新格式化并重新在 SD 卡上重新安装 Raspbian OS。在 SD 卡的引导驱动器中创建新的“wpa_supplicant.conf”文件也不起作用。幸运的是,我找到了使用 Python 脚本连接到新网络的解决方案,但在此之前,您需要先执行这些步骤。

    解决方案:不要使用with open('/etc/wpa_supplicant/wpa_supplicant.conf', 'w') as file: 重写“wpa_supplicant.conf”,而是从/etc/network/interfaces 路径重写“interfaces”文件。

    将此代码添加到“interfaces”文件的source-directory /etc/network/interfaces.d 行下方:

    auto wlan0
    iface wlan0 inet dhcp
    wpa-ssid "WIFI NETWORK NAME HERE"
    wpa-psk "WIFI NETWORK PASSWORD HERE"
    

    保存“interfaces”文件并打开“wpa_supplicant.conf”文件。

    ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdevnetwork={... 的行之间添加update_config=1。根据我的观察,这有点忽略了network={... 的内容,并将其对Wi-Fi 信息的检索转移到/etc/network/interfaces 文件中。

    保存文件并重新启动。

    重新启动后,您可以通过执行 Python 脚本来重写 /etc/network/interfaces 文件,只要您想更改为新网络(该脚本必须在最后导致系统重新启动,以便新的 Wi-Fi 更改为生效)。 (我不知道'interfaces'文件是否允许添加多个网络,到目前为止我一次只测试了一个网络,因为这已经实现了我的项目目标。)这是一个Python代码示例来更改'interfaces' 文件中的网络信息:

    import os
    import time
    
    SSID = input('Enter SSID: ')
    password = input("Enter password: ")
    
    with open('/etc/network/interfaces', 'w') as file:
        content = \
            '# interfaces(5) file used by ifup(8) and ifdown(8)\n\n' + \
            '# Please note that this file is written to be used with dhcpcd\n' + \
            "# For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf'\n" + \
            '# Include files from /etc/network/interfaces.d:\n' + \
            'source-directory /etc/network/interfaces.d\n' + \
            'auto wlan0\n' + \
            'iface wlan0 inet dhcp\n' + \
            'wpa-ssid "' + SSID + '"\n' + \
            'wpa-psk "' + password + '"\n'
    
        file.write(content)
    
    print("Write successful. Rebooting now.")
    time.sleep(2)
    os.system('sudo reboot now')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-08
      • 2015-04-01
      • 2016-05-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多