如何允许非默认用户使用串行设备ttyUSB0?

我有一个Ubuntu 11.10系统,有两个用户:
- 第一个是在安装过程中创建的。 - 第二个是之后创建的,属于sudoers组。
现在的问题是,当第二个用户尝试使用设备ttyUSB0时,会返回以下错误:
"Could not open serial port /dev/ttyUSB0"

我通过使用以下方法成功修复了它:
sudo chown :second_user /dev/ttyUSB0

然而,当我断开设备并重新连接时,问题又出现了。
有没有办法让不同的用户访问这些设备? 我想我必须将用户添加到特定的组中。目前所有者是root,组是dialout。但是我对组不太确定,也不知道如何添加用户。
谢谢!
7个回答

正如您所注意到的,/dev/ttyUSB0 设备属于 dialout 组。您只需要将第二个用户添加到 dialout 组即可:
sudo adduser second_user dialout

此更改生效后,second_user需要注销并重新登录。


谢谢Jeremy!这个方法对SSH访问也适用吗?因为当我通过SSH访问电脑时,我看到有两个同名用户。我猜其中一个是本地用户,另一个是SSH用户。我该如何将所有权交给SSH用户呢? - Maverik
1这将允许 second_user 从任何登录、ssh 或本地访问串口。您不需要将所有权分配给该用户的特定登录。 - Jeremy Kerr
2是的,你说得对。我不得不注销然后再次登录才能通过SSH访问。 - Maverik
对于自动登录的用户会话,您需要重新启动计算机,而不仅仅是重新登录到X Window系统。在Ubuntu 19.04上观察到这个问题。 - tanius
5sudo usermod -a -G dialout $USER - Martijn van Wezel

简单的方法:
sudoedit /etc/udev/rules.d/50-myusb.rules

保存这段文字:
KERNEL=="ttyUSB[0-9]*",MODE="0666"
KERNEL=="ttyACM[0-9]*",MODE="0666"

拔掉设备,然后重新插上,这样任何用户都可以读写它!

在14.04版本中适用于自制设备的ttyACM插口。谢谢。+1 - NonStandardModel
在重新连接之前,你需要这样做来重新加载规则吗?sudo udevadm control --reload - Alexis Paques
根据存储您的/etc/udev的文件系统以及您使用的udev版本,您可能确实需要显式重新加载。但在我使用过的大多数机器上,udev似乎会自动解决这个问题(使用inotify)。 - Orion Lawlor
1这真的不是应该这样做的方式。USB串行设备应该属于dialout组或类似的组,并且用户应该被添加到该组中。然而,你提出的方法对于其他类型的USB设备可能是有道理的。 - Chris Stratton

你可以使用UDEV。这是一个系统,每次插入或拔出设备时都会触发(还有其他东西)。借助它,你可以编写脚本来执行各种操作,包括设置权限。
运行sudoedit /etc/udev/rules.d/50-ttyusb.rules并将以下内容添加进去:
KERNEL=="ttyUSB[0-9]*",NAME="tts/USB%n",SYMLINK+="%k",GROUP="uucp",MODE="0666"

保存,退出并重新插拔设备,然后您应该可以正常运行了。将权限设置为666允许任何人对设备进行写入。
我是根据这个页面来做的,这个页面是几年前的,但如果Jeremy的解决方案不起作用,类似这样的方法应该可以。

1这对我有用,也就是说,我使用了udev规则,但我改变了语法以适应我的情况。http://linux.m2osw.com/sane-cannot-find-any-scanners -- 请注意,如果您使用MODE="0666",那么您可能不需要GROUP。只有其中之一会有用。 - Alexis Wilke

太棒了 - 这里提供的UDEV解决方案对我来说非常有用。
我通过Wine安装了Icom的CS-F3020_F5010_F5020程序,并按照以下方式创建了Com端口的链接:
ln -s /dev/ttyUSB0 ~/.wine/dosdevices/com1 but nothing. 

然后我意识到我需要更改/dev/ttyUSB0上的权限以允许我访问它。这样做很好,直到您拔下/重新插入USB,然后您需要重新更改权限。

我尝试将我的用户添加到dialout组,但由于某种原因,这未解决问题。

使用UDEV解决了最后一块拼图。现在我可以在Linux中编程我的Icom无线电,插拔USB/串行设备不再有任何麻烦。喔耶。谢谢。


udev规则是有效的,但是按照现有的写法,它们会产生一个非常严重的副作用,即使所有的ttyUSB*设备对每个人都是可访问的。这并不好,因为根据系统上还有什么其他内容,这可能构成安全风险。
相反,应该使用更加选择性的udev规则。例如,我有一个USB设备,它操作一组开关。当插入时,通过dmesg可以看到制造商的ID和产品代码(甚至在这种情况下,还有设备的序列号)。可以添加以下内容:
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001"

将上述内核行和规则应用于该设备。更好的做法是不仅将其分配给MODE变量,还要设置组:
GROUP="whatever", MODE="0660"

只有组'whatever'的成员才能获得写权限。
约翰·鲍勒

你也可以使用chmod(我在树莓派Linux上做过)。
在我的情况下,sudo adduser pi dialout没有起作用("用户'pi'已经是'dialout'的成员"),但非root应用程序仍然无法访问串口。
请参考它们的链接(/dev/serial0 -> /dev/ttyS0)。
pi@raspberrypi:~ $ ls -al /dev/serial*
lrwxrwxrwx 1 root root 5 Dec 30 18:03 /dev/serial0 -> ttyS0
lrwxrwxrwx 1 root root 7 Dec 30 18:03 /dev/serial1 -> ttyAMA0
pi@raspberrypi:~ $ ls -al /dev/ttyS*
crw--w---- 1 root tty 4, 64 Jan  7 16:07 /dev/ttyS0

更新所有用户的读写权限。
pi@raspberrypi:~ $ sudo chmod ugo+rw /dev/ttyS0

现在用户代码(例如 'pi' 用户 dotnet core 应用程序)可以访问 /dev/serial0