如何使用C程序查找可移动设备的序列号
How to find the serial number of removable devices using C program
我正在使用 bash 脚本为我的另一个应用程序获取可移动设备(如笔式驱动器)的序列号。
是否可以在本机 C 中执行,有人可以将此 bash 转换为 C。
#!/bin/bash
for C in `ls /sys/block/`; do
RE=`cat /sys/block/$C/removable`
if [ $RE == "1" ] ;then
#VENDOR=`/bin/udevadm info --name=/dev/$C | grep ID_VENDOR=|awk -F"=" ' { print }'`
#MODEL=`/bin/udevadm info --name=/dev/$C | grep ID_MODEL=|awk -F"=" ' { print }'`
#SERIAL=`/bin/udevadm info --name=/dev/$C | grep SERIAL_SHORT|awk -F"=" ' { print }'`
#echo $VENDOR-$MODEL"-"$SERIAL #print as per your taste
USB_SERIAL=`/bin/udevadm info --name=/dev/$C | grep ID_SERIAL=|awk -F"=" ' { print }'|awk -F"-" ' { print }'`
echo $USB_SERIAL #or just the default one
fi
done
我不想使用系统调用。想要纯C程序
这里的关键挑战是,因为您不想使用 system()
,所以要模仿 udevadm info
的工作方式。下面的程序通过读取 /run/udev/data/b<i>MAJOR</i>:<i>MINOR</i> 中的信息来做到这一点(至少在我的系统上是这样)
,其中 MAJOR 和 MINOR 是我们从 /sys/block/<i>NAME</i>/dev
,其中NAME是块设备名称。
#include <dirent.h>
#include <stdio.h>
int main()
{
struct dirent *entry; // read thru the entries in "/sys/block"
for (DIR *dirp = opendir("/sys/block"); entry = readdir(dirp); )
if (entry->d_type == DT_LNK) // the relevant files are symbolic links
{
char path[277];
sprintf(path, "/sys/block/%s/removable", entry->d_name);
FILE *fp = fopen(path, "r"); if (!fp) return perror(path), 1;
int re; // read the /sys/block/%s/removable flag
fscanf(fp, "%d", &re), fclose(fp);
if (re)
{ // read the device's MAJOR:MINOR numbers
sprintf(path, "/sys/block/%s/dev", entry->d_name);
fp = fopen(path, "r"); if (!fp) return perror(path), 1;
fscanf(fp, "%s", path+sprintf(path, "/run/udev/data/b")),
fclose(fp);
fp = fopen(path, "r"); if (!fp) return perror(path), 1;
char USB_serial[NAME_MAX]; // scan the udev/data for ID_SERIAL=
while (fgets(path, sizeof path, fp))
if (sscanf(path, "E:ID_SERIAL=%[^-]", USB_serial) > 0)
puts(USB_serial);
fclose(fp);
}
}
}
我正在使用 bash 脚本为我的另一个应用程序获取可移动设备(如笔式驱动器)的序列号。 是否可以在本机 C 中执行,有人可以将此 bash 转换为 C。
#!/bin/bash
for C in `ls /sys/block/`; do
RE=`cat /sys/block/$C/removable`
if [ $RE == "1" ] ;then
#VENDOR=`/bin/udevadm info --name=/dev/$C | grep ID_VENDOR=|awk -F"=" ' { print }'`
#MODEL=`/bin/udevadm info --name=/dev/$C | grep ID_MODEL=|awk -F"=" ' { print }'`
#SERIAL=`/bin/udevadm info --name=/dev/$C | grep SERIAL_SHORT|awk -F"=" ' { print }'`
#echo $VENDOR-$MODEL"-"$SERIAL #print as per your taste
USB_SERIAL=`/bin/udevadm info --name=/dev/$C | grep ID_SERIAL=|awk -F"=" ' { print }'|awk -F"-" ' { print }'`
echo $USB_SERIAL #or just the default one
fi
done
我不想使用系统调用。想要纯C程序
这里的关键挑战是,因为您不想使用 system()
,所以要模仿 udevadm info
的工作方式。下面的程序通过读取 /run/udev/data/b<i>MAJOR</i>:<i>MINOR</i> 中的信息来做到这一点(至少在我的系统上是这样)
,其中 MAJOR 和 MINOR 是我们从 /sys/block/<i>NAME</i>/dev
,其中NAME是块设备名称。
#include <dirent.h>
#include <stdio.h>
int main()
{
struct dirent *entry; // read thru the entries in "/sys/block"
for (DIR *dirp = opendir("/sys/block"); entry = readdir(dirp); )
if (entry->d_type == DT_LNK) // the relevant files are symbolic links
{
char path[277];
sprintf(path, "/sys/block/%s/removable", entry->d_name);
FILE *fp = fopen(path, "r"); if (!fp) return perror(path), 1;
int re; // read the /sys/block/%s/removable flag
fscanf(fp, "%d", &re), fclose(fp);
if (re)
{ // read the device's MAJOR:MINOR numbers
sprintf(path, "/sys/block/%s/dev", entry->d_name);
fp = fopen(path, "r"); if (!fp) return perror(path), 1;
fscanf(fp, "%s", path+sprintf(path, "/run/udev/data/b")),
fclose(fp);
fp = fopen(path, "r"); if (!fp) return perror(path), 1;
char USB_serial[NAME_MAX]; // scan the udev/data for ID_SERIAL=
while (fgets(path, sizeof path, fp))
if (sscanf(path, "E:ID_SERIAL=%[^-]", USB_serial) > 0)
puts(USB_serial);
fclose(fp);
}
}
}