(抱歉英语不好,我是德国人)
我正在尝试在linux上编写一个程序,用于在插入的任何插入的USB闪存设备上写入数据。
但是这个:
file = fopen("/run/media/abc/xyz/logFile.txt", "w");
如果用户名不是abc,或者设备名称不是xyz或linux不希望我的程序运行,将失败。
我找到了一个输出这个的程序:
sysfs /sys
proc /proc
devtmpfs /dev
securityfs /sys/kernel/security
tmpfs /dev/shm
devpts /dev/pts
tmpfs /run
tmpfs /sys/fs/cgroup
cgroup /sys/fs/cgroup/systemd
pstore /sys/fs/pstore
cgroup /sys/fs/cgroup/freezer
cgroup /sys/fs/cgroup/cpu,cpuacct
cgroup /sys/fs/cgroup/perf_event
cgroup /sys/fs/cgroup/memory
cgroup /sys/fs/cgroup/pids
cgroup /sys/fs/cgroup/net_cls,net_prio
cgroup /sys/fs/cgroup/blkio
cgroup /sys/fs/cgroup/devices
cgroup /sys/fs/cgroup/cpuset
cgroup /sys/fs/cgroup/hugetlb
configfs /sys/kernel/config
/dev/mapper/fedora_msi--linux-root /
selinuxfs /sys/fs/selinux
systemd-1 /proc/sys/fs/binfmt_misc
debugfs /sys/kernel/debug
hugetlbfs /dev/hugepages
tmpfs /tmp
mqueue /dev/mqueue
binfmt_misc /proc/sys/fs/binfmt_misc
nfsd /proc/fs/nfsd
/dev/sda1 /boot
/dev/mapper/fedora_msi--linux-home /home
sunrpc /var/lib/nfs/rpc_pipefs
tmpfs /run/user/1000
gvfsd-fuse /run/user/1000/gvfs
fusectl /sys/fs/fuse/connections
/dev/sdc1 /run/media/username/usbname
但是对我来说使用它看起来很糟糕,我不知道如何区分“/ dev / sdc1 / run / media / username / usbname”(右边的)和“/ dev / sda1 / boot” (假的)。
注意:本程序不必在非Linux操作系统上运行。
注意:我不想直接写入/ dev / sdc1
如果有人知道如何找到正确的安装点,或者有人给我一个(官方)文档的链接,我将感激不尽。
答案 0 :(得分:2)
在Linux中,通常需要将连接的设备挂载到文件系统的目录中,以便从中读取和写入。
在你的情况下,我可以看到你的发行版(也许是Ubuntu?)已经将设备安装到/ run / media / username / usbname中,这已经为最终用户自动完成。因此,您的代码可能适用于此发行版,并且不适用于其他人(甚至在Ubuntu服务器中),这需要手动完成安装进度。
我可以建议您研究像this这样的教程来了解如何在Linux上使用usb闪存驱动器。如何使用命令行手动安装设备。
然后自己制作一个目录,根据需要命名。在插入设备时自动将设备挂载到该目录(可能是一点Bash脚本)
最后,您可以使用C ++在目录中执行任何操作,而无需担心名称更改。
<强>更新强>
如何知道设备是否已插好?
每次插入usb时,dmesg
都会为事件写入日志。这是我插入32GB金士顿USB时Ubuntu桌面的示例。
....
[ 39.647394] scsi 4:0:0:0: Direct-Access Kingston DataTraveler 3.0 PMAP PQ: 0 ANSI: 6
[ 39.647950] sd 4:0:0:0: Attached scsi generic sg1 type 0
[ 41.108262] sd 4:0:0:0: [sdb] 60632064 512-byte logical blocks: (31.0 GB/28.9 GiB)
[ 41.108722] sd 4:0:0:0: [sdb] Write Protect is off
[ 41.108726] sd 4:0:0:0: [sdb] Mode Sense: 23 00 00 00
[ 41.109185] sd 4:0:0:0: [sdb] No Caching mode page found
[ 41.109190] sd 4:0:0:0: [sdb] Assuming drive cache: write through
[ 41.114913] sdb: sdb1
[ 41.120164] sd 4:0:0:0: [sdb] Attached SCSI removable disk
然后mount
命令(没有root权限)可以为您提供文件系统中的挂载点。例如:
/dev/sdb1 on /media/nuc/MULTIBOOT type fuseblk (rw,nosuid,nodev,allow_other,default_permissions,blksize=4096)
或者,您也可以阅读/proc/mounts
来获取相同的报告。
如何自动将所有这些信息提供给我的代码?
这是你的工作。在C / C ++中,您可以触发命令到Shell,获取输出字符串,使用关键字进行分析。来自Linux的输出报告非常普遍,这意味着您预计它会不时出现。
答案 1 :(得分:0)
在Linux中,你没有(通常,它取决于你使用的发行版)安装usb设备的固定路径。即使您没有自动挂载它们(这是您的发行版中配置的内容,但不是一般问题)。因此,没有通用的标准方法来检测某些USB设备是否已经插入和安装。
自动挂载usb设备的过程来自udevd(8)
,即负责检测有关插入设备的内核事件的守护程序进入linux可以附加的几条总线,接收消息告诉某些特殊设备已经附加并安装适当的设备驱动程序以应对它(通常,对于usb pendrive,这是一系列设备驱动程序,终止于在/dev/...
中创建设备inode并在适用时安装它们的脚本)。如果您阅读了该守护程序文档,您将看到如何安装一个shell脚本,该脚本将在您检测到新的已插入设备并且已准备好安装后立即执行。
这个shell脚本应该做什么。好吧,如果你想保守一点,你就不会覆盖插入的每个设备,如果你没有检测到别的东西,那么你就可以识别插入的设备。这可以是一个特殊标记的分区或类似的东西,它允许您识别要覆盖或不覆盖的设备。它可以像设备根目录中的魔术名称一样简单。
为了务实并为您提供无需阅读长手册页的解决方案,应该定期扫描挂载表(您可以从/proc/mounts
获取它或读取输出mount(8)
命令)并检测自上次执行以来哪些条目已更改。如果添加了一些条目,只需检查(来自mount(8)
命令的条目具有格式mount_device\tmount_directory\tmount_options\t...
,您必须保持mount_directory
以检查是否有一些特殊的命名文件,然后继续复制你想要的所有信息。
要定期检查挂载表,您必须在crontab(7)
文件中包含以下内容:
* * * * check_mounts.sh
这个shell脚本将每分钟执行一次以完成这种工作。
一些有用的东西是写一个时间戳,表明你最后一次向插件设备写信息的时间,这样你就可以获得自你上次写信息以来发生了什么变化的信息(这可能是内容您用来检查此挂载点是否适合写入您要存储的信息的特殊文件