前言
这几天为了完成导师的任务在封校的苦闷日子中找一点乐趣,想着怎么对自己的u盘进行一些操作,让我能够读取固定位置的数据。
然后我就苦逼得找了两天。
其实早就找到了 这一杀器,问题是我不知道怎么执行scsi命令。
下面介绍一下最强大的u盘工具:
sg3_utils
所谓 ,实际上是封装好的c函数库,安装好后可以直接在系统内调用相关函数来执行u disk相关操作。完善支持macos,linux,windows
安装
安装有大坑,至少我在linux上是这样。
先介绍我的 环境:
1 | Ubuntu: 21.20 |
---|
安装有两种方式,一:
1 | sudo apt-get install sg3-utils |
---|
我未尝试该方法,该方法可能会出现一些问题。
另一种是在官网通过源码编译安装,我下载的是1.47.tar.xz。
之后的安装方式是这样的:
1234 | sudo ./configure --prefix=/usr --disable-static && make#之后:sudo make install |
---|
这里解释一下,--disable-static
会阻止安装时采用依赖库的静态版本(参考博文),如果不这样做,可能会在执行命令时
产生和我一样的错误:
1 | error while loading shared libraries: libsgutils2.so.1.47: cannot open shared object file: No such file or directory |
---|
即便采用软链接的方式把libsgutils2.so.2
链接到libgutils2.so.147
也不行。
我在这里耽误了好久,最终找到上文中的博文才知道是安装是出了问题。
使用
在我的 环境中,要读取u disk指定位置的内容,首先查看u盘名称:
123456789 | > df -h文件系统 容量 已用 可用 已用% 挂载点tmpfs 1.4G 3.7M 1.4G 1% /run/dev/nvme0n1p8 428G 207G 200G 51% /tmpfs 6.8G 163M 6.7G 3% /dev/shmtmpfs 5.0M 4.0K 5.0M 1% /run/lock/dev/nvme0n1p1 256M 34M 223M 14% /boot/efitmpfs 1.4G 188K 1.4G 1% /run/user/1000/dev/sda1 30G 112K 30G 1% /media/heeler/UBUNTU 21_0 |
---|
我对linux的了解并不深,其中 /dev/sda1
与根目录下的 /dev/sg0
应为同一个设备,应该是linux对u盘不同功能的区分,实际上还是同一个设备。
之后我们可以对u disk进行读取操作了:
12345 | ❯ sudo sg_read if=/dev/sg0 bs=512 count=2kB mmap=1 time=1[sudo] heeler 的密码: Time for all SCSI READ commands was 0.016853 secs, 60.76 MB/secAverage number of SCSI READ commands per second was 949.392000 0 records in, SCSI READ commands issued: 16 |
---|
sg_read
属于 sg3_utils
的一个函数,其官方介绍在网址, if
参数指定挂载的文件系统, bs
是要读取的每一个块(block,我不知道怎么翻译)的大小,这里是对每一个块读取512字节, count
相当于读取的数据量,这里是读取2kb大小的块, time
相当于开启一个计时选项,当然sg_read还有很多参数可选,具体参数请参考官方文档。
当然,我们不能只是一行行的敲shell命令,那么怎么把命令写在脚本里面呢?
我首先尝试了写一个1.sh脚本:
1 | sg_read if=/dev/sg0 bs=512 count=2kB mmap=1 time=1 |
---|
然后sudo ./1.sh
,会显示commod not found;或者在su -root下sudo ./1.sh
显示权限不够,原因在于1.sh要求读取系统层面的文件,而sg_read并没有添加到系统配置里面,所以显示command not found或者权限不够,具体原因我还不是很了解。
那么我们怎么办呢?
上
我写了一个脚本1.py,在 sudo python3 1.py
就可以了。下面是py脚本:
12345 | import osprocess=os.popen("sg_read if=/dev/sg0 bs=512 count=2kB mmap=1 time=1")output=process.read()process.close()print(output) |
---|
用上python之后,就可以加一些奇技淫巧了。比如添加随机数据,随机读取数据以测量u disk的性能。
写在最后
不得不说,从 开始真的痛苦, 某人没人指导,没人给方向,前半部分时间我一直在研究一个脚本,他通过直接调用内核参数来实现对u disk的操作。我还大致浏览了一些scsi的书籍,比如来自mit的scsi,结果屁用没有成功提高了我对scsi的理解。这也是我写出这篇博客的动力,帮助人们认识到 这个强大的工具。 也有一个go写的框架,但现在还没有一个较完善的功能。总之,对u disk进行操作的话,我还是建议使用sg3_utils这个完善、强大的工具。