繁体   English   中英

Python fcntl.ioctl [Errno 1] 不允许操作

[英]Python fcntl.ioctl [Errno 1] Operation not permitted

我正在尝试使用 bluetooth_utils.py 运行 python 程序,以从温度/湿度设备读取蓝牙通知。 它在以 root 权限 (sudo) 运行时工作正常,但无法以普通用户 (在这种情况下为 Raspberry 上的 pi) 运行。 我尝试使用以下代码行将错误语句与我的程序和库隔离:

from __future__ import absolute_import
import sys
import struct
import fcntl
import array
import socket
from errno import EALREADY
import bluetooth._bluetooth as bluez
from bluetooth_utils import (toggle_device, enable_le_scan,
                             parse_le_advertising_events,
                             disable_le_scan, raw_packet_to_str)
dev_id = 0
enable = True
hci_sock = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, socket.BTPROTO_HCI)
print("Power %s bluetooth device %d" % ('ON' if enable else 'OFF', dev_id))
req_str = struct.pack("H", dev_id)
request = array.array("b", req_str)
hci_sock.fileno()
bluez.HCIDEVUP
bluez.HCIDEVDOWN
fcntl.ioctl(hci_sock.fileno(), bluez.HCIDEVUP if enable else bluez.HCIDEVDOWN, request[0])
toggle_device(dev_id, False)

以下是使用 pi 运行时的结果(只是在解释器中复制/粘贴):

pi@raspberrypi:~ $ python
Python 2.7.16 (default, Oct 10 2019, 22:02:15) 
[GCC 8.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from __future__ import absolute_import
>>> import sys
>>> import struct
>>> import fcntl
>>> import array
>>> import socket
>>> from errno import EALREADY
>>> import bluetooth._bluetooth as bluez
>>> from bluetooth_utils import (toggle_device, enable_le_scan,
...                              parse_le_advertising_events,
...                              disable_le_scan, raw_packet_to_str)
>>> dev_id = 0
>>> enable = True
>>> hci_sock = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, socket.BTPROTO_HCI)
>>> print("Power %s bluetooth device %d" % ('ON' if enable else 'OFF', dev_id))
Power ON bluetooth device 0
>>> req_str = struct.pack("H", dev_id)
>>> request = array.array("b", req_str)
>>> hci_sock.fileno()
3
>>> bluez.HCIDEVUP
1074022601
>>> bluez.HCIDEVDOWN
1074022602
>>> fcntl.ioctl(hci_sock.fileno(), bluez.HCIDEVUP if enable else bluez.HCIDEVDOWN, request[0])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 1] Operation not permitted
>>> 

当我使用 sudo (sudo python) 运行程序时,它运行良好。

>>> from __future__ import absolute_import
>>> import sys
>>> import struct
>>> import fcntl
>>> import array
>>> import socket
>>> from errno import EALREADY
>>> import bluetooth._bluetooth as bluez
>>> from bluetooth_utils import (toggle_device, enable_le_scan,
...                              parse_le_advertising_events,
...                              disable_le_scan, raw_packet_to_str)
>>> dev_id = 0
>>> enable = True
>>> hci_sock = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, socket.BTPROTO_HCI)
>>> print("Power %s bluetooth device %d" % ('ON' if enable else 'OFF', dev_id))
Power ON bluetooth device 0
>>> req_str = struct.pack("H", dev_id)
>>> request = array.array("b", req_str)
>>> hci_sock.fileno()
3
>>> bluez.HCIDEVUP
1074022601
>>> bluez.HCIDEVDOWN
1074022602
>>> fcntl.ioctl(hci_sock.fileno(), bluez.HCIDEVUP if enable else bluez.HCIDEVDOWN, request[0])
0
>>> toggle_device(dev_id, False)
Power OFF bluetooth device 0
>>>

试图在某些资源上找到有关底层权限的信息,但除了控制台之类的通信端口之外找不到其他任何东西......

非常感谢您的帮助。

丹尼尔。

好的,我相信我找到了解决此问题的方法:

$ sudo setcap cap_net_raw,cap_net_admin+eip $(eval readlink -f `which python3`)

它通过为 python3 可执行文件提供额外的权限(特定于网络相关的东西)来解决问题。 每次更新 python3 可执行文件时,我还需要重新应用此命令。 关于此命令的附加信息:

$ man setcap
$ man capabilities

至少,它能让我前进……

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM