<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[判断U盘是否插入，获取U盘设备名和挂载路径]]></title><description><![CDATA[<p dir="auto"><strong>1，判断是否有U盘插入</strong></p>
<blockquote>
<p dir="auto">ls /sys/class/scsi_device/<br />
为空则没有U盘，有类似0:0:0:0的目录则有U盘插入</p>
</blockquote>
<p dir="auto"><strong>2，获取U盘设备名</strong></p>
<blockquote>
<p dir="auto">ls /sys/class/scsi_device/[U盘号如:0:0:0:0]/device/block<br />
路径下目录名即为设备名，通过设备命就可以查询U盘挂载路径了</p>
</blockquote>
<p dir="auto"><strong>3，查询U盘挂载路径</strong></p>
<blockquote>
<p dir="auto">cat /proc/mounts | grep [设备名如:sda]<br />
为空则未挂载，虽然通过命令：</p>
<p dir="auto">df -h | grep sda<br />
也可以获取挂载路径，但是一个设备可以同时挂载在多个地方，而df -h只显示最后一次挂载的位置。</p>
</blockquote>
<p dir="auto"><strong>4，手动挂载</strong><br />
若设备未挂载则需要自己手动挂载，直接使用mount命令挂载的，无法直接使用普通用户操作U盘内文件，可用以下命令：</p>
<blockquote>
<p dir="auto">sudo mount -t vfat -o uid=用户名如：pi,gid=用户组名如:pi,umask=0000 /dev/设备名如sda1 挂载路径如：/tmp/udisk</p>
</blockquote>
]]></description><link>https://bbs.aw-ol.com/topic/1434/判断u盘是否插入-获取u盘设备名和挂载路径</link><generator>RSS for Node</generator><lastBuildDate>Fri, 17 Apr 2026 09:45:37 GMT</lastBuildDate><atom:link href="https://bbs.aw-ol.com/topic/1434.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 15 May 2022 04:55:18 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to 判断U盘是否插入，获取U盘设备名和挂载路径 on Sun, 15 May 2022 05:08:53 GMT]]></title><description><![CDATA[<p dir="auto"><a href="https://blog.csdn.net/u014304293/article/details/40212591" target="_blank" rel="noopener noreferrer nofollow ugc">linux下u盘检测程序</a></p>
<p dir="auto">获得U盘的插入或者拔取得信息的传统方法是在内核级运行hotplug程序，相关参数通过环境变量传递过来，再由hotplug通知其他关注hotplug的应用程序,但是效率比较低.</p>
<p dir="auto">网上查找知道:</p>
<p dir="auto">用户空间的程序与设备通信的方法，主要有以下几种方式，<br />
　　1. 通过ioperm获取操作IO端口的权限，然后用inb/inw/ inl/ outb/outw/outl等函数，避开设备驱动程序，直接去操作IO端口。（没有用过）</p>
<p dir="auto">2. 用ioctl函数去操作/dev目录下对应的设备，这是设备驱动程序提供的接口。像键盘、鼠标和触摸屏等输入设备一般都是这样做的。</p>
<p dir="auto">3. 用write/read/mmap去操作/dev目录下对应的设备，这也是设备驱动程序提供的接口。像framebuffer等都是这样做的。</p>
<p dir="auto">上面的方法在大多数情况下，都可以正常工作，但是对于热插拨(hotplug)的设备，比如像U盘，就有点困难了，因为不知道：什么时候设备插上了，什么时候设备拔掉了。这就是所谓的hotplug问题了。</p>
<p dir="auto">新的方法是采用<strong>NETLINK实现</strong>的，这是一种特殊类型的socket，专门用于内核空间与用户空间的异步通信。</p>
<p dir="auto">先说明几个总要的结构体:</p>
<p dir="auto">sockaddr_nl结构：</p>
<pre><code>      struct sockaddr_nl {
                       sa_family_t nl_family;    //AF_NETLINK
                       unsigned short nl_pad;    // 0
                       pid_t nl_pid;         // 进程pid
                        u_32 nl_groups;      // 多播组掩码
                   }nl;

  int setsockopt(
                      SOCKET s,
                      int level,
                      int optname,
                      const char* optval,
                      int optlen
                );
</code></pre>
<blockquote>
<p dir="auto">s(套接字): 指向一个打开的套接口描述字<br />
level:(级别)： 指定选项代码的类型。<br />
SOL_SOCKET: 基本套接口<br />
IPPROTO_IP: IPv4套接口<br />
IPPROTO_IPV6: IPv6套接口<br />
IPPROTO_TCP: TCP套接口<br />
optname(选项名)： 选项名称<br />
optval(选项值): 是一个指向变量的指针 类型：整形，套接口结构， 其他结构类型:linger{}, timeval{ }<br />
optlen(选项长度) ：optval 的大小</p>
</blockquote>
<p dir="auto">贴出代码:</p>
<pre><code>#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
#include &lt;sys/socket.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;linux/netlink.h&gt;
#include &lt;dirent.h&gt;
#include &lt;sys/statfs.h&gt;
 
int init_socket()
{
	struct sockaddr_nl snl;
	const int BufferSize= 1024;
	int retval;
	
	memset(&amp;snl,0,sizeof(struct sockaddr_nl));
	snl.nl_family = AF_NETLINK;
	snl.nl_pid = getpid();
	snl.nl_groups = 1;
	
	int Sock_id = socket(PF_NETLINK,SOCK_DGRAM,NETLINK_KOBJECT_UEVENT);
	
	if(Sock_id == -1)
	printf("sock err:%m\n"),exit(-1);
	
	// set reveive buffer
	setsockopt(Sock_id,SOL_SOCKET,SO_RCVBUFFORCE,&amp;BufferSize,sizeof(BufferSize));
	retval = bind(Sock_id,(struct sockaddr*)&amp;snl,sizeof(struct sockaddr_nl));
	if(retval==-1)
	printf("bind err:%m\n"),close(Sock_id),exit(-1);
	return Sock_id;
}
 
// 该函数主要作用时检测u盘的 总空间,剩余空间,剩余空间百分比
double GetDiskFreeSpacePercent(const char *pDisk,double* freespace,double*  totalspace)
{
	struct statfs disk_statfs;
	double freeSpacePercent =0;
	if(statfs(pDisk,&amp;disk_statfs) == 0)
	{
		
		*freespace = (disk_statfs.f_bsize * disk_statfs.f_bfree) / (1024*1024*1024.0);
		*totalspace = (disk_statfs.f_bsize * disk_statfs.f_blocks) / (1024*1024*1024.0);
	}
	return freeSpacePercent = (*freespace)/(*totalspace)*100;
 
}
 
#define BUFFER_SIZE 2048
 
int main()
{
	DIR *dp;
	double f=0;
	double t=0;
	double percent=0;
	const char* path="/media/cjl/disk";
	int sd= init_socket();
	while(1)
	{
		char buf[BUFFER_SIZE] = {0};
		recv(sd,&amp;buf,sizeof(buf),0);
		//printf("%s\n",buf);
			if(!memcmp(buf,"add@",4) /*&amp;&amp; !memcmp(&amp;buf[strlen(buf) - 4],"/sdb",4)*/)
		{
			printf("Found U Disk\n");
			break;
		}
	}
	printf("是否打开u盘Y/N\n");
	char c;
	scanf("%c",&amp;c);
	if(c=='Y' || c=='y')
	{
		if((dp = opendir(path)) ==NULL)
		{
			printf("打开失败!\n");
		}
		else
		{
			system("ls -l /media/cjl/disk");
		}
	}
	else if(c=='N' || c=='n')
	
	percent = GetDiskFreeSpacePercent(path,&amp;f,&amp;t);
	
	printf("u盘剩余空间: %.2f\n",f);
	printf("u盘总空间:   %.2f\n",t);
	printf("u盘剩余空间百分比: %0.2f%%\n",percent);
	return 0;
}
</code></pre>
<p dir="auto"><img src="/assets/uploads/files/1652591248762-e7592ce1-a7f8-4d79-ad82-c6ac9a9b3aa2-image.png" alt="e7592ce1-a7f8-4d79-ad82-c6ac9a9b3aa2-image.png" class=" img-responsive img-markdown" width="305" height="124" /></p>
]]></description><link>https://bbs.aw-ol.com/post/6817</link><guid isPermaLink="true">https://bbs.aw-ol.com/post/6817</guid><dc:creator><![CDATA[ubuntu]]></dc:creator><pubDate>Sun, 15 May 2022 05:08:53 GMT</pubDate></item><item><title><![CDATA[Reply to 判断U盘是否插入，获取U盘设备名和挂载路径 on Sun, 15 May 2022 04:57:13 GMT]]></title><description><![CDATA[<p dir="auto">usb设备的检测及区分(sata硬盘、优盘及移动硬盘)</p>
<p dir="auto">原理：<br />
1.如果有外置usb设备插入，会产生/proc/scsi/usb-storage目录(ide硬盘上默认<br />
没有)，并且会在/proc/scsi/usb-storage目录中产生数字文件，此文件存储了设<br />
备的相关信息。</p>
<p dir="auto">2./sys/class/scsi_device/目录中会有几个scsi设备的目录，以数字开头。(ide<br />
中默认无子目录，sata硬盘默认有子目录),类似1:0:0或2:0:0,开头的数字,这个数<br />
字与/proc/scsi/usb-storage目录中的相对应，另外的子目录表示sata硬盘。</p>
<p dir="auto">3.在/sys/class/scsi_device/数字开头的目录/device/目录下以block开头的目录<br />
中(可能为block或block:sda或block:sdb或block:scr等,总之这里只有一个以<br />
block开头的目录）有两个文件：<br />
removeable和dev.<br />
removeable的内容为0或1,可以区分优盘或移动硬盘。<br />
dev的内容类似8:16，就是/proc/partitions中设备的maj:min的值。<br />
据此，先看usb-storage目录，再到/sys目录下找相应的removable和dev文件，再<br />
查partitions文件，就可以得到设备名、设备信息、可移动标记。</p>
]]></description><link>https://bbs.aw-ol.com/post/6816</link><guid isPermaLink="true">https://bbs.aw-ol.com/post/6816</guid><dc:creator><![CDATA[ubuntu]]></dc:creator><pubDate>Sun, 15 May 2022 04:57:13 GMT</pubDate></item></channel></rss>